首頁  >  文章  >  web前端  >  組件是vue的特性嗎

組件是vue的特性嗎

青灯夜游
青灯夜游原創
2022-07-21 19:31:271976瀏覽

元件是vue的特性,它是Vue最強大的功能之一。在Vue中,元件可以擴充HTML元素,封裝可重複使用的程式碼;在較高層面上,元件是自訂元素,Vue的編譯器為它增加特殊功能;在某些情況下,元件也可以是原生HTML元素的形式,以is特性擴展。

組件是vue的特性嗎

本教學操作環境:windows7系統、vue3版,DELL G3電腦。

Vue.js 是一個優秀的前端介面開發 JavaScript 函式庫,它之所以非常火,是因為有眾多突出的特點,其中主要的特點有以下幾個。

1) 輕量級的框架

Vue.js 能夠自動追蹤依賴的模板表達式和計算屬性,提供MVVM 資料綁定和一個可組合的組件系統,具有簡單、靈活的API,讓讀者更容易理解,能夠更快上手。

2) 雙向資料綁定

宣告式渲染是資料雙向綁定的主要體現,同樣也是Vue.js 的核心,它允許採用簡潔的模板語法將資料聲明式渲染整合進DOM。

3) 指令

Vue.js 與頁面進行交互,主要是透過內建指令來完成的,指令的作用是當其表達式的值改變時相應地將某些行為應用到DOM 上。

4) 元件化

元件(Component)是 Vue.js 最強大的功能之一。元件可以擴充 HTML 元素,封裝可重複使用的程式碼。在較高層面上,元件是自訂元素,Vue.js 的編譯器為它添加特殊功能。在某些情況下,元件也可以是原生 HTML 元素的形式,以 is 特性擴充。

在 Vue 中,父子元件透過 props 傳遞通信,從父向子單傳遞。子元件與父元件通信,透過觸發事件通知父元件改變資料。這樣就形成了一個基本的父子通訊模式。

在開發中元件和 HTML、JavaScript 等有非常緊密的關係時,可以根據實際的需求自訂元件,使開發變得更加便利,可大幅減少程式碼編寫量。

元件也支援熱重載(hotreload)。當我們做了修改時,不會刷新頁面,只是對元件本身進行立刻重載,不會影響整個應用程式目前的狀態。 CSS 也支援熱重載。

元件的優點:

  • 降低整個系統的耦合度,在保持介面不變的情況下,我們可以取代不同的元件快速完成需求,例如輸入框,可以替換為日曆、時間、範圍等元件作具體的實作

  • 調試方便,由於整個系統是透過元件組合起來的,在出現問題的時候,可以用排除法直接移除組件,或根據報錯的組件快速定位問題,之所以能夠快速定位,是因為每個組件之間低耦合,職責單一,所以邏輯會比分析整個系統要簡單

  • #提高可維護性,由於每個元件的職責單一,並且元件在系統中是被重複使用的,所以對程式碼進行最佳化可獲得系統的整體升級

5) 客戶端路由

Vue-router 是Vue.js 官方的路由插件,與Vue.js 深度集成,用於建立單頁應用程式。 Vue 單頁面應用程式是基於路由和元件的,路由用於設定存取路徑,並將路徑和元件映射起來,傳統的頁面是透過超連結實現頁面的切換和跳躍的。

6) 狀態管理

狀態管理其實是單向的資料流,State 驅動View 的渲染,而使用者對View 進行動作產生Action,使State產生變化,從而使View 重新渲染,形成一個單獨的元件。

初識VUE元件應用

#實例化多個vue物件

用new創建多個vue物件並命名,可以透過變數相互存取

範例:物件2修改物件1的name變數

<!-- 第一个根元素 -->
<div>这里是:{{name}}</div> 

<!-- 第二个根元素 -->
<div>
    <p>这里是:{{name}}</p>
<br>
    <button>change-one-name</button>
    <!-- 点击后修改vue-app-one的name值-->
</div>
 // 第一个vue对象
var one = new Vue({
    el:"#vue-app-one",
    data:{
        "name":"ccy1"
    }
})

 // 第二个vue对象
var two = new Vue({
    el:"#vue-app-two",
    data:{
        "name":"ccy2"
    },
    methods:{
        // 修改vue-app-one的name为'ccy333'
        changeName:function(){
            one.name = 'ccy333'
        }
    }
})

效果:點擊後修改」ccy1「為」ccy333「

組件是vue的特性嗎

全域元件

#定義與使用

  • 定義全域元件,需給元件一個名字,呼叫時,將元件名稱當作標籤名稱使用;相當於自訂標籤,該標籤下可以包含很多子html標籤;
  • 這些子html標籤定義在元件的template屬性中,每次呼叫該元件,都渲染template裡的標籤
  • template裡必須只有一個根元素
  • 在元件中, data是函數,將資料return回去
  • 依然可以用this來呼叫data中定義的資料

範例:

定義元件:

① 定义一个组件,命名为my-component
② 其中包含数据:name和方法:changeName
③ 渲染出的html效果有一个p标签,包含一个按钮,点击按钮时,修改name
④ 命名规范:camelCase (驼峰命名法) 与kebab-case (短横线分隔命名)

  • 当写成标签时,遇到有大写字母的命名,需要改成小写并用横杆链接前后两个部分,如定义组件时命名为myComponent,写成标签时应写成my-component>;
  • 组件定义时也可以用横杆法命名;
  • 如果定义时用myComponent,标签用my-component>是OK的,系统自动识别
// 自定义的全局组件my-component
// template中只有一个根元素p标签,里面包含一个button按钮
Vue.component('my-component',{
    template:`<p>
        我的名字是:{{name}}
        <button>btn</button>
        </p>`,
    data(){
        return {
            name:'ccy'
        }
    },
    methods:{
        changeName:function(){
            this.name = '安之'
        }
    }
})
// vue对象1
new Vue({
    el:"#vue-app-one",
})
// vue对象2
new Vue({
    el:"#vue-app-two",
})

使用组件:

① 在vue对象对应的根元素(el指定标签)下使用
② 由于定义的是全局组件,所以可以在任意的vue对象下使用
③ 组件可复用,在一个vue对象下可以使用多次,且组件间互相独立

<div>
    <my-component></my-component>
    <my-component></my-component>
</div> 

<div>
    <my-component></my-component>
</div>

效果:

組件是vue的特性嗎

data是一个函数

在vue对象中,data属性值是一个对象,比如这样的:

組件是vue的特性嗎

      但是在全局组件中,同一份data可能被多个vue对象使用,每个对象不单独维护一份data时,如果某一个vue对象修改了data中的一个变量,其他vue对象获取data时就会被影响;

      如果用上面的例子做案例,若组件中的data是对象(引用),其他地方均不改变,两个vue对象便共享同一个name变量;当我通过其中一个vue对象改变name数据时(即点击任一个btn按钮),另一个对象获得的name也发生了改变(其他按钮处的’ccy’也都被改成了’安之’)

      因此,为保证数据的独立性,即每个实例可以维护一份被返回对象的独立的拷贝,data为每个实例都return一份新创建的数据,不同的vue对象获取的data均互不影响

      在vscode中不允许组件中的data是对象,会报错:

      [Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.

局部组件

  • 局部组件注册在某个vue对象中,
  • 只有注册过该局部组件的vue对象才能使用这个局部组件

例子:

局部组件定义:

// template仅一个根元素:ul
var msgComponent = {
	// 数据是自身提供的 (hobbies)
    template:`
  • {{hobby}}
`,     data(){         return {             hobbies:['看剧','看动漫','吃好吃的']         }     } }

注册局部组件:

// 仅由注册过该局部组件的vue对象才能使用,此处为div#vue-app-one
// 注意命名规范,components中对象的key将会被作为标签名,多个单词拼接的命名需使用横杆法
// 可以写成msg-component,此处直接简化了命名为msg,
new Vue({
    el:"#vue-app-one",
    components:{
        "msg": msgComponent
    }
})

html文件中使用<msg></msg>

<div>
    <p>这里是vue-app-one</p>
    <mycomponent></mycomponent>
    <mycomponent></mycomponent>
    <p>我的爱好:</p>
    <msg></msg> <!--使用局部组件-->
</div>

效果: 红框圈出的部分就是局部组件渲染出来的

組件是vue的特性嗎

父向子传值/传引用:prop

静态传值

创建子组件:

var titleComponent = {
    props:["title"],
    template:`<p>{{title}}</p>`
    // 所需要的数据title由父组件提供
}

在父组件的components属性中注册子组件:

new Vue({
    el:"#vue-app-one",
    components:{
        "msg": msgComponent,
        "titleComponent":titleComponent
    },
})

在父组件上使用子组件:

<!-- div#vue-app-one为父组件 -->
<div>
    <p>这里是vue-app-one</p>
    <mycomponent></mycomponent>
    <mycomponent></mycomponent>
	<!--使用子组件title-component,并传值"我的爱好:"给子组件-->
    <title-component></title-component>
    <msg></msg>
</div>

效果:红框标记处就是父向子传值并展示

組件是vue的特性嗎

动态传值:v-bind

定义子组件:

var titleComponent = {
    props:["title"],
    template:`<p>{{title}}</p>`
}

在父组件的components属性中注册子组件:

new Vue({
    el:"#vue-app-one",
    components:{
        "msg": msgComponent,
        "titleComponent":titleComponent
    },
    data(){
        return {
            title:"my hobbies are ",
        }
    }
})

使用子组件,通过绑定父组件data中的变量title来实现动态传值:

<!-- div#vue-app-one为父组件 -->
<div>
    <p>这里是vue-app-one</p>
    <mycomponent></mycomponent>
    <mycomponent></mycomponent>
    <!-- 动态绑定title -->
    <title-component></title-component>
    <msg></msg>
</div>

效果:红框处就是动态绑定获取数据的展示

組件是vue的特性嗎 

传递数组等复杂数据时,也可以使用v-bind来动态传值,如:
需要向子级传递hobbies数组,在vue实例对象(父)中创建数据hobbies

new Vue({
    el:"#vue-app-one",
    components:{
        "msg": msgComponent,
        "titleComponent":titleComponent
    },
    data:{
        title:"my hobbies are ",
        hobbies:['看剧','看动漫','吃好吃的'], //需要向子组件传递的数据
    }
})

定义子组件

var msgComponent = {
    template:`
            <p>{{hobby}}</p>
            `,
    props:["hobby"],
    data(){
        return {   
        }
    }
}

使用子组件

<!-- div#vue-app-one为父组件 -->
<div>
    <p>这里是vue-app-one</p>
    <mycomponent></mycomponent>
    <mycomponent></mycomponent>
    <title-component></title-component>
    <!-- 动态传值:hobbies -->
    <msg></msg>
</div>

效果:

組件是vue的特性嗎

跳回“一点想法”处

子向父:事件传值$emit

        子组件不能通过prop向父组件传递数据,需要使用事件向父组件抛出一个值,告知父组件我需要实现一个功能,由父组件处理这个事件

例子:点击按钮,改变名称chinesename
(由于data变量名不支持chinese-name形式,花括号里不支持chineseName形式,所以这里我都用了小写,此处记录一下,日后学到了新知再来填坑)

先在父组件的data中定义chinesename的初始值:

new Vue({
    el:"#vue-app-one",
    data:{
         chinesename:"anzhi" // chinesename初始值
    }
})

创建子组件,并注册事件change-name(就像click事件一样,需要让系统能够辨认这是一个事件并监听,当事件被触发时,执行某项约定好的操作):

  Vue.component('blog-post', {
    props: ['chinesename'],
    template: `
      <div>
        <h4>{{ chinesename }}</h4>
        <button>
            修改名字
        </button>
      </div>
    `
    // blog-post组件包含一个h4,显示chinesename,和一个按钮
    // 点击这个按钮,触发change-name事件,将"ruosu"作为参数传递给指定的处理函数onChangeName
  })

在父组件中使用子组件,定义change-name的处理函数为onChangeName:

<div>
    <p>这里是vue-app-one</p>
	<!-- v-bind:通过prop给子组件传递chinesename的初始值 -->
	<!-- v-on:子组件通过$emit给父组件传递新的chinesename的值 -->
	<div>
	      <blog-post></blog-post>
	</div>
</div>

在父组件处定义事件处理函数onChangeName:

new Vue({
    el:"#vue-app-one",
    data:{
          chinesename:"anzhi"
    },
    methods:{
        onChangeName:function(value){
        	// 将chinesename换成传递过来的数据
            this.chinesename=value
        }
    }
})

效果:

組件是vue的特性嗎

一点想法

关于父子组件的区分,在此写一点总结,还是日后学了新知识再来填坑 

      官网中没有很明确指明两者的定义和区别,在网上搜了一圈,觉得比较多人认可并且好理解的是:

  • el指定的根元素为父组件(使用之处为父组件)
  • vue实例对象也可看做组件

      在前面这些父子传值的例子中,我们可以看到,对于局部组件,我们会在某个html根元素中注册并使用,所以此时el指定的根元素在html文件中是这个局部组件的父组件,局部组件在html使用时便是这个父组件的一份子,承担数据传输的责任
跳转到父向子动态传值案例

組件是vue的特性嗎

組件是vue的特性嗎

      再用绕口令说一波,即:title-component组件定义处与使用处,两者身份是不一样的,在定义处,它是局部组件,也是子组件,需注册才能使用;在使用处,它是根元素的包含一部分,根元素为父组件,而“它”,承担着父组件与子组件数据沟通的重任

这个总结在全局组件情况下也适用,使用该全局组件的根元素是父组件,如上面的子向父传值的案例,p#vue-app-one是父组件,作为父子组件沟通的桥梁,全局组件blog-post为子组件

图示:

組件是vue的特性嗎


如果是子组件又嵌套了子组件,被嵌套的组件是子子组件,以此类推

【相关视频教程推荐:vue视频教程web前端入门

以上是組件是vue的特性嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn