Vue-5個進階構造屬性
本章介紹:directive、mixin、extend、provide&inject這5個Vue的進階構造屬性。
Directive-指令
-
什麼是指令?
其實之前我們就已經學習了指令,如:
v-if
、v-for
,類似這些以 v- 開頭的就是指令,而v-if
、v-for
這些屬於內建指令,除此之外我們還可以自定義指令。 -
全域性自定義指令
全域性自定義指令:在全域性作用域下自定義指令,同時這個指令也能夠用於全域性,即任何元件都能夠使用這個全域性指令。如要宣告多個全域性指令,多次呼叫
Vue.directive
// 宣告全域性指令,注意在全域性作用域下 Vue.directive('x',directiveOptions) // 使用全域性指令,在任何元件中都可以使用 v-x <myComponent v-x ></myComponent> 複製程式碼
-
區域性自定義指令
區域性自定義指令:在某個元件Vue物件下進行宣告,只能在該Vue元件的例項中使用。注意區域性宣告時的 directives。
// 宣告區域性指令 <script> export default { ... directives:{ "x":directiveOptions, "y":directiveOptions } } </script> // 只能在該元件中使用區域性指令 <template> <div v-x v-y></div> </template> 複製程式碼
-
directiveOptions
在上面的宣告中,我們只是演示了指令的宣告,並沒有研究如何賦予指令功能,而指令的功能是通過directiveOptions中的5個鉤子函式來實現的。
- directiveOptions中的5個鉤子函式:
- bind:可以看成Vue中的created函式,即:當使用該指令的VNode(虛擬DOM)載入到記憶體中時執行的鉤子函式。
- inserted:被繫結元素插入父節點時呼叫。
- update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。
- componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。
- unbind:只呼叫一次,指令與元素解綁時呼叫。
- 鉤子函式被傳入的4個引數:(el,binding,vnode,oldVnode)
- 第一個引數el:指令所繫結的元素,可以用來直接操作DOM。
- 第二個引數binding:這是一個物件,包含下列屬性
- name:指令名,不包括
v-
字首 - value:指令的繫結值,如:
v-on:click='sayhi'
,這個sayhi就是指令繫結值。 - oldValue:指令繫結的前一個值,僅在
update
和componentUpdated
鉤子中可用。無論值是否改變都可用。 - expression:字串形式的指令表示式,如:
v-on:click='sayhi'
,這裡'sayhi'
就是指令表示式。 - arg:傳給指令的引數,如:
v-on:click='sayhi'
,這個click
就是傳給指令的引數。 - modifiers:一個包含修飾符的物件。 例如:
v-my-directive.foo.bar
中,修飾符物件為{ foo: true, bar: true }
。
- name:指令名,不包括
- 第三個引數vnode:Vue 編譯生成的虛擬節點。
- 第四個引數oldVnode:Vue 編譯生成的上一個虛擬節點。
- directiveOptions中的5個鉤子函式:
-
使用directiveOptions完整宣告一個指令
下面我們通過一個小例子,來簡單實現Vue內建指令
v-on
的繫結事件的功能。new Vue({ directives: { "myOn": { inserted: (el, info) => { el.addEventListener(info.arg, info.value) } } } }) 複製程式碼
-
指令的作用以及使用場景
Vue元件/例項的主要用於資料繫結、事件監聽、DOM更新,而指令的作用主要是完成原生DOM操作。
當我們需要重複多次相同的原生DOM操作,或者是進行一些比較複雜的原生DOM操作時,可以藉助指令來完成。
mixins-組合
-
什麼是mixins?
簡單來說就是“複製”。有時候我們需要使用多次相同的元件,這些元件的程式碼幾乎一樣,為了節省程式碼量,我們可以將這些相同的部分提取出來,然後通過mixin組合到各自元件中。mixins中的操作會合併到其他Vue例項中後,當作一個整體執行:比如:mixin中沒有某個變數,但是其它Vue例項中有,這種情況下並不會報錯,因是先合併了才執行。
-
mixins的意義
mixins可以減少data、methods、鉤子的重複使用。
-
mixins的使用
// 相同部分提取 log.js export default { data(){ return { a:'a' } }, methods:{ hw:function(){ console.log('helloWorld') } }, created:function(){ console.log('created') } } 複製程式碼
// 在元件中使用提取的部分 myComponent.vue import log from './log.js' export default { // 這裡是個陣列,說明可以使用多個mixins mixins:[log], data(){ return { b:'b' } } } // 此時,這元件就可以使用mixins中的 a資料 ,hw方法 ,created ,以及自身的 b資料 複製程式碼
-
mixins是智慧合併的
相同data當前例項優先順序更高,而相同的鉤子函式則會把兩邊的操作都合併起來。
-
全域性mixin
Vue.mixin({mixin物件}) 複製程式碼
注意:全域性mixin宣告時沒有s(mixin)。使用全域性mixin後,所有的元件包括App.vue都會預設合併這個全域性mixin,所以不建議使用全域性mixin。
extends-繼承
-
extends的作用
extends的作用和mixins一樣,但是形式不同。
-
extends的使用
1.區域性extends的使用
// 宣告擴充套件內容 const myVue = {} // 使用 export default { // 注意這裡不是陣列 extends:myVue, data(){ return {} } } 複製程式碼
-
全域性extends的使用
// 全域性宣告 const myVue = Vue.extend({擴充套件內容}) // 繼承式宣告Vue例項 new myVue({vueOptions}) 複製程式碼
-
extends與extends&mixins
extends宣告的擴充套件內容還能夠使用extends和mixins。
import log from './log.js' // mixin const com1 = {} const com2 = { extends:com1, mixins:[log] } 複製程式碼
-
provide提供&inject注入
-
什麼是provide和inject?
上級元件可以通過provide傳遞data與method,而下級元件可以通過inject獲取上級元件傳遞的data與method。
provide和inject能夠大範圍傳遞data和methods
-
provide和inject的使用方法
// 上級元件 export default { data(){ return { n:'n'} }, methods:{ add(){ console.log('add') } }, provide(){ return { n:this.n, add:this.add } } } // 下級元件 // 我們就可以在下級元件中,使用n與add export default { inject:['n','add'] } 複製程式碼
-
provide和inject使用細節
傳遞的data時,父元件把自身data的地址複製了一份傳遞了,子元件能夠獲取data的值,但如果想在子元件中修改父元件的某些data(簡單型別如Number、String)是不允許的,因為我們修改的只是複製的變數的值。但是我們可以通過在子元件中呼叫父元件傳遞過裡啊的method來修改父元件的data,因為傳遞過來的method內部關聯的是父元件的data。
但是如果父元件provide的data是一個物件,由於上級元件複製的是一個地址,所以子元件訪問的也是同一個物件,那麼在子元件中是能夠修改這個物件,進而影響到父元件的。不推薦傳遞一個provide一個物件,因為如果都使用這個方法,那麼在元件較多的情況下很難確定那個物件當前是出於什麼狀態。