Vue.js組件使用開發(fā)實例教程
組件
組件可以擴(kuò)展HTML元素,封裝可重用的代碼,在較高的層面上,組件是自定義元素,vue.js的編譯器為它添加特殊功能,在有些情況下,組件也可以是原生HTML元素的形式,以is特性擴(kuò)展。
Vue.js的組件可以理解為預(yù)先定義好了行為的ViewModel類。一個組件可以預(yù)定義很多選項,但最核心的是以下幾個:
模板(template):模板聲明了數(shù)據(jù)和最終展現(xiàn)給用戶的DOM之間的映射關(guān)系。
初始數(shù)據(jù)(data):一個組件的初始數(shù)據(jù)狀態(tài)。對于可復(fù)用的組件來說,這通常是私有的狀態(tài)。
接受的外部參數(shù)(props):組件之間通過參數(shù)來進(jìn)行數(shù)據(jù)的傳遞和共享。參數(shù)默認(rèn)是單向綁定(由上至下),但也可以顯式地聲明為雙向綁定。
方法(methods):對數(shù)據(jù)的改動操作一般都在組件的方法內(nèi)進(jìn)行??梢酝ㄟ^v-on指令將用戶輸入事件和組件方法進(jìn)行綁定。
生命周期鉤子函數(shù)(lifecycle hooks):一個組件會觸發(fā)多個生命周期鉤子函數(shù),比如created,attached,destroyed等等。在這些鉤子函數(shù)中,我們可以封裝一些自定義的邏輯。和傳統(tǒng)的MVC相比,可以理解為 Controller的邏輯被分散到了這些鉤子函數(shù)中。
私有資源(assets):Vue.js當(dāng)中將用戶自定義的指令、過濾器、組件等統(tǒng)稱為資源。由于全局注冊資源容易導(dǎo)致命名沖突,一個組件可以聲明自己的私有資源。私有資源只有該組件和它的子組件可以調(diào)用。
除此之外,同一顆組件樹之內(nèi)的組件之間還可以通過內(nèi)建的事件API來進(jìn)行通信。Vue.js提供了完善的定義、復(fù)用和嵌套組件的API,讓開發(fā)者可以像搭積木一樣用組件拼出整個應(yīng)用的界面。
組件大大提高了代碼的效率和維護(hù)性以及復(fù)用率。
使用組件
注冊
1.創(chuàng)建一個組件構(gòu)造器:
var MyComponent = Vue.extend({ //選項 })
2.將構(gòu)造器用做組件,用Vue.component(tag,constructor)注冊:
Vue.component('my-component',MyComponent)
3.在父實例的模塊中以自定義元素<my-component>的形式使用:
<div id = "example"> <my-component></my-component> </div>
例子:
<div id="example"> <my-component></my-component> </div> // 定義 var MyComponent = Vue.extend({ template: '<div>A custom component!</div>' }) // 注冊 Vue.component('my-component', MyComponent) // 創(chuàng)建根實例 new Vue({ el: '#example' })
渲染為:
<div id = "example"> <div>A custom component!</div> </div>
組件的模板替換了自定義元素,自定義元素的作用只是作為一個掛載點??梢杂脤嵗x項 replace 決定是否替換。
局部注冊
用實例選項components注冊,不需要全局注冊每個組件,可以讓組件只能用在其他組件內(nèi):
var Child = Vue.extend({ /* ... */ }) var Parent = Vue.extend({ template: '...', components: { // <my-component> 只能用在父組件模板內(nèi) 'my-component': Child } })
這種封裝也適用于其它資源,如指令、過濾器和過渡。
注冊語法糖
// 在一個步驟中擴(kuò)展與注冊 Vue.component('my-component', { template: '<div>A custom component!</div>' }) // 局部注冊也可以這么做 var Parent = Vue.extend({ components: { 'my-component': { template: '<div>A custom component!</div>' } } })
組件選項問題
傳入Vue構(gòu)造器的多數(shù)選項也可以用在Vue.extend()中,除了data和el,如果簡單的把一個對象作為data選項傳給Vue.extend(),則所有的實例將共享同一個data對象,因此我們應(yīng)當(dāng)使用一個函數(shù)作為data選項,讓這個函數(shù)返回一個新對象:
var MyComponent = Vue.extend({ data: function () { return { a: 1 } } })
模板解析
Vue的模板是DOM模板,使用瀏覽器原生的解析器,所以它必須是有效的HTML片段,一些HTML元素對什么元素可以放在它里面有限制,常見的限制有:
a 不能包含其它的交互元素(如按鈕,鏈接)
ul 和 ol 只能直接包含 li
select 只能包含 option 和 optgroup
table 只能直接包含 thead, tbody, tfoot, tr, caption, col, colgroup
tr 只能直接包含 th 和 td
在實際中,這些限制會導(dǎo)致意外的結(jié)果。盡管在簡單的情況下它可能可以工作,但是你不能依賴自定義組件在瀏覽器驗證之前的展開結(jié)果。例如
<my-select><option>...</option></my-select> 不是有效的模板,即使 my-select 組件最終展開為 <select>...</select>。
另一個結(jié)果是,自定義標(biāo)簽(包括自定義元素和特殊標(biāo)簽,如 <component>、<template>、 <partial> )不能用在 ul, select, table 等對內(nèi)部元素有限制的標(biāo)簽內(nèi)。放在這些元素內(nèi)部的自定義標(biāo)簽將被提到元素的外面,因而渲染不正確。
對于自定義元素,應(yīng)當(dāng)使用 is 特性:
<table>
<tr is="my-component"></tr> </table> //<template> 不能用在 <table> 內(nèi),這時應(yīng)使用 <tbody>,<table> 可以有多個 <tbody> <table> <tbody v-for="item in items"> <tr>Even row</tr> <tr>Odd row</tr> </tbody> </table>
Props
使用props傳遞數(shù)據(jù)
組件實例的作用域是孤立的,可以使用props把數(shù)組傳給子組件,props是組件數(shù)據(jù)的一個字段,期望從父組件傳下來,子組件需要顯式地用props選項聲明props:
Vue.component('child', { // 聲明 props props: ['msg'], // prop 可以用在模板內(nèi) // 可以用 `this.msg` 設(shè)置 template: '<span>{{ msg }}</span>' })
然后向它傳入一個普通字符串:
<child msg="hello!"></child>
動態(tài)props
用v-bind綁定動態(tài)props到父組件的數(shù)據(jù),每當(dāng)父組件的數(shù)據(jù)變化時,也會傳導(dǎo)給子組件:
<div> <input v-model="parentMsg"> <child v-bind:my-message="parentMsg"></child> //<child :my-message="parentMsg"></child> </div>
props綁定類型
prop默認(rèn)是單向綁定,當(dāng)父組件的屬性變化時,將傳導(dǎo)給子組件,但是反過來不會,這是為了防止子組件無意修改了父組件的狀態(tài),可以使用.sync或.once綁定修飾符顯式地強制雙向或單次綁定:
<!-- 默認(rèn)為單向綁定 --> <child :msg="parentMsg"></child> <!-- 雙向綁定 --> <child :msg.sync="parentMsg"></child> <!-- 單次綁定 --> <child :msg.once="parentMsg"></child>
如果 prop 是一個對象或數(shù)組,是按引用傳遞。在子組件內(nèi)修改它會影響父組件的狀態(tài),不管是使用哪種綁定類型。
父子組件通信
父鏈
子組件可以用this.$parent訪問它的父組件,根實例的后代可以用this.$root訪問它,父組件有一個數(shù)組this.$children,包含它所有的子元素
自定義事件
Vue實例實現(xiàn)了一個自定義事件接口,用于在組件樹中通信,這個事件系統(tǒng)獨立于原生DOM事件,用法也不同,每一個Vue實例都是一個事件觸發(fā)器:
使用 $on() 監(jiān)聽事件;
使用 $emit() 在它上面觸發(fā)事件;
使用 $dispatch() 派發(fā)事件,事件沿著父鏈冒泡;
使用 $broadcast() 廣播事件,事件向下傳導(dǎo)給所有的后代。
不同于 DOM 事件,Vue 事件在冒泡過程中第一次觸發(fā)回調(diào)之后自動停止冒泡,除非回調(diào)明確返回 true。
<!-- 子組件模板 --> <template id="child-template"> <input v-model="msg"> <button v-on:click="notify">Dispatch Event</button> </template> <!-- 父組件模板 --> <div id="events-example"> <p>Messages: {{ messages | json }}</p> <child></child> </div> // 注冊子組件 // 將當(dāng)前消息派發(fā)出去 Vue.component('child', { template: '#child-template', data: function () { return { msg: 'hello' } }, methods: { notify: function () { if (this.msg.trim()) { this.$dispatch('child-msg', this.msg) this.msg = '' } } } }) // 初始化父組件 // 將收到消息時將事件推入一個數(shù)組 var parent = new Vue({ el: '#events-example', data: { messages: [] }, // 在創(chuàng)建實例時 `events` 選項簡單地調(diào)用 `$on` events: { 'child-msg': function (msg) { // 事件回調(diào)內(nèi)的 `this` 自動綁定到注冊它的實例上 this.messages.push(msg) } } })
效果:
使用v-on綁定自定義事件
在模板中子組件用到的地方聲明事件處理器,為此子組件可以用v-on監(jiān)聽自定義事件:
<child v-on:child-msg="handleIt"></child>
當(dāng)子組件觸發(fā)了 "child-msg" 事件,父組件的 handleIt 方法將被調(diào)用。所有影響父組件狀態(tài)的代碼放到父組件的 handleIt 方法中;子組件只關(guān)注觸發(fā)事件。
子組件索引
使用v-ref為子組件指定一個索引ID,可以直接訪問子組件
<div id="parent"> <user-profile v-ref:profile></user-profile> </div> var parent = new Vue({ el: '#parent' }) // 訪問子組件 var child = parent.$refs.profile
使用Slot分發(fā)內(nèi)容
內(nèi)容分發(fā):混合父組件的內(nèi)容與子組件自己的模板的方式,使用特殊的<slot>元素作為原始內(nèi)容的插槽。
編譯作用域
父組件模板的內(nèi)容在父組件作用域內(nèi)編譯;子組件模板的內(nèi)容在子組件作用域內(nèi)編譯。
綁定子組件內(nèi)的指令到一個組件的根節(jié)點:
Vue.component('child-component', { // 有效,因為是在正確的作用域內(nèi) template: '<div v-show="someChildProperty">Child</div>', data: function () { return { someChildProperty: true } } })
類似地,分發(fā)內(nèi)容是在父組件作用域內(nèi)編譯。
單個slot
父組件的內(nèi)容將被拋棄,除非子組件模板包含<slot>,如果子組件模板只有一個沒有特性的slot,父組件的整個內(nèi)容將插到slot所在的地方并替換它。
<slot> 標(biāo)簽的內(nèi)容視為回退內(nèi)容?;赝藘?nèi)容在子組件的作用域內(nèi)編譯,當(dāng)宿主元素為空并且沒有內(nèi)容供插入時顯示這個回退內(nèi)容。
假定 my-component 組件有下面模板:
<div> <h1>This is my component!</h1> <slot>
如果沒有分發(fā)內(nèi)容則顯示我。
</slot> </div>
父組件模板:
<my-component> <p>This is some original content</p> <p>This is some more original content</p> </my-component>
渲染結(jié)果:
<div> <h1>This is my component!</h1> <p>This is some original content</p> <p>This is some more original content</p> </div>
具名slot
<slot>元素可以用一個特殊特性name配置如何分發(fā)內(nèi)容,多個slot可以有不同的名字,具名slot將匹配內(nèi)容片段中有對應(yīng)slot特性的元素。
仍然可以有一個匿名 slot,它是默認(rèn) slot,作為找不到匹配的內(nèi)容片段的回退插槽。如果沒有默認(rèn)的 slot,這些找不到匹配的內(nèi)容片段將被拋棄。
動態(tài)組件
多個組件可以使用同一個掛載點,然后動態(tài)地在它們之間切換,使用保留的<component>元素,動態(tài)地綁定到它的is特性:
new Vue({ el: 'body', data: { currentView: 'home' }, components: { home: { /* ... */ }, posts: { /* ... */ }, archive: { /* ... */ } } }) <component :is="currentView"> <!-- 組件在 vm.currentview 變化時改變 --> </component>
keep-alive
把切換出去的組件保留在內(nèi)存中,可以保留它的狀態(tài)或避免重新渲染。
<component :is="currentView" keep-alive>
<!-- 非活動組件將被緩存 -->
</component>
activate鉤子
控制組件切換時長,activate 鉤子只作用于動態(tài)組件切換或靜態(tài)組件初始化渲染的過程中,不作用于使用實例方法手工插入的過程中。
Vue.component('activate-example', { activate: function (done) { var self = this loadDataAsync(function (data) { self.someData = data done() }) } })
transition-mode
transition-mode 特性用于指定兩個動態(tài)組件之間如何過渡。
在默認(rèn)情況下,進(jìn)入與離開平滑地過渡。這個特性可以指定另外兩種模式:
in-out:新組件先過渡進(jìn)入,等它的過渡完成之后當(dāng)前組件過渡出去。
out-in:當(dāng)前組件先過渡出去,等它的過渡完成之后新組件過渡進(jìn)入。
示例:
<!-- 先淡出再淡入 --> <component :is="view" transition="fade" transition-mode="out-in"> </component> .fade-transition { transition: opacity .3s ease; } .fade-enter, .fade-leave { opacity: 0; }
Vue.js 組件 API 來自三部分——prop,事件和 slot:
prop 允許外部環(huán)境傳遞數(shù)據(jù)給組件;
事件 允許組件觸發(fā)外部環(huán)境的 action;
slot 允許外部環(huán)境插入內(nèi)容到組件的視圖結(jié)構(gòu)內(nèi)。
以上所述是小編給大家介紹的Vue.js組件使用開發(fā)實例教程,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
關(guān)于Vue新搭檔TypeScript快速入門實踐
這篇文章主要介紹了關(guān)于Vue新搭檔TypeScript快速入門實踐,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09基于Vue實現(xiàn)可選擇不連續(xù)的時間范圍的日期選擇器
這篇文章主要為大家詳細(xì)介紹了如何基于Vue.js實現(xiàn)一個可選擇不連續(xù)的時間范圍的日期選擇器,文中的示例代碼簡潔易懂,需要的可以參考一下2023-06-06Vue 中使用vue2-highcharts實現(xiàn)top功能的示例
下面小編就為大家分享一篇Vue 中使用vue2-highcharts實現(xiàn)top功能的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03vue.js學(xué)習(xí)筆記之v-bind和v-on解析
這篇文章主要介紹了vue.js學(xué)習(xí)筆記之v-bind和v-on解析,v-bind 指令用于響應(yīng)地更新 HTML 特征,v-on 指令用于監(jiān)聽DOM事件,文中還給大家提到了v-bind,v-on的縮寫,感興趣的朋友參考下吧2018-05-05vue父組件與子組件之間的數(shù)據(jù)交互方式詳解
最近一直在做一個vue移動端商城的實戰(zhàn),期間遇到一個小小的問題,值得一說,下面這篇文章主要給大家介紹了關(guān)于vue父組件與子組件之間數(shù)據(jù)交互的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11vue-cli 環(huán)境變量 process.env的使用及說明
這篇文章主要介紹了vue-cli 環(huán)境變量 process.env的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12