本章介紹:directive、mixin、extend、provide&inject這5個Vue的進階構造屬性。javascript
什麼是指令?html
其實以前咱們就已經學習了指令,如:v-if
、v-for
,相似這些以 v- 開頭的就是指令,而v-if
、v-for
這些屬於內置指令,除此以外咱們還能夠自定義指令。vue
全局自定義指令java
全局自定義指令:在全局做用域下自定義指令,同時這個指令也可以用於全局,即任何組件都可以使用這個全局指令。如要聲明多個全局指令,屢次調用Vue.directive
node
// 聲明全局指令,注意在全局做用域下
Vue.directive('x',directiveOptions)
// 使用全局指令,在任何組件中均可以使用 v-x
<myComponent v-x ></myComponent>
複製代碼
局部自定義指令express
局部自定義指令:在某個組件Vue對象下進行聲明,只能在該Vue組件的實例中使用。注意局部聲明時的 directives。數組
// 聲明局部指令
<script>
export default {
...
directives:{
"x":directiveOptions,
"y":directiveOptions
}
}
</script>
// 只能在該組件中使用局部指令
<template>
<div v-x v-y></div>
</template>
複製代碼
directiveOptionside
在上面的聲明中,咱們只是演示了指令的聲明,並無研究如何賦予指令功能,而指令的功能是經過directiveOptions中的5個鉤子函數來實現的。函數
v-
前綴v-on:click='sayhi'
,這個sayhi就是指令綁定值。update
和 componentUpdated
鉤子中可用。不管值是否改變均可用。v-on:click='sayhi'
,這裏'sayhi'
就是指令表達式。v-on:click='sayhi'
,這個click
就是傳給指令的參數。v-my-directive.foo.bar
中,修飾符對象爲 { foo: true, bar: true }
。使用directiveOptions完整聲明一個指令學習
下面咱們經過一個小例子,來簡單實現Vue內置指令v-on
的綁定事件的功能。
new Vue({
directives: {
"myOn": {
inserted: (el, info) => {
el.addEventListener(info.arg, info.value)
}
}
}
})
複製代碼
指令的做用以及使用場景
Vue組件/實例的主要用於數據綁定、事件監聽、DOM更新,而指令的做用主要是完成原生DOM操做。
當咱們須要重複屢次相同的原生DOM操做,或者是進行一些比較複雜的原生DOM操做時,能夠藉助指令來完成。
什麼是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的做用和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傳遞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一個對象,由於若是都使用這個方法,那麼在組件較多的狀況下很難肯定那個對象當前是出於什麼狀態。