首先,我們都知道vue有很多內(nèi)置指令,比如:v-if,v-show,v-html等等,有些時候我們需要自己定義指令處理項目中的一些問題,下面就按官網(wǎng)的案例開始學(xué)習(xí),此篇僅作為學(xué)習(xí)記錄。
全局指令和局部指令
// main.js 不一定非得叫這個名稱
// 全局指令
Vue.directive('focus', {
// 當(dāng)被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// xxx.vue文件
// 局部指令
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
鉤子函數(shù)
一個指令定義對象可以提供如下幾個鉤子函數(shù) (均為可選):
- bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進行一次性的初始化設(shè)置。
- inserted:被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)。
- update:所在組件的 VNode 更新時調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細的鉤子函數(shù)參數(shù)見下)。
- componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
- unbind:只調(diào)用一次,指令與元素解綁時調(diào)用
鉤子參數(shù)
// html
<div id="app" v-demo:foo.a.b="message"></div>
// js
Vue.directive('demo', {
bind: function (el, binding, vnode) {
// el: 指令所綁定的元素,可以用來直接操作 DOM,除了el外,其他參數(shù)都是只讀的,請勿修改
**binding對象,內(nèi)容如下
// binding.name: 指令的名字,不帶v-的部分,此案例中的demo
// binding.value: 指令綁定的值,=號后面的部分,此案例中的message的值,即"hello!"。也可以傳對象。
// binding.oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。
// binding.expression: 字符串形式的指令表達式,此案例中真正的message
// binding.arg: 指令的參數(shù),冒號后面的第一個值,此案例中的foo
// binding.modifiers: 一個包含修飾符的對象, 冒號后面第二個及以后的值,以{ foo: true, bar: true }的形式展示
**vnode對象
// vnode: Vue 編譯生成的虛擬節(jié)點。包含tag,text,children,data等等
}
})
new Vue({
el: '#app',
data: {
message: 'hello!'
}
})

binding對象輸出結(jié)果
動態(tài)參數(shù)
拿上面的案例,binding.arg是寫死的foo,我們有時候想要動態(tài)的值
// xxx.vue
<div id="app">
<p v-pin:[direction]="200">我要偏移200px,但是我要根據(jù)direction來判斷方向</p>
</div>
// js
Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var s = (binding.arg == 'left' ? 'left' : 'top')
el.style[s] = binding.value + 'px'
}
})
new Vue({
el: '#app',
data: function () {
return {
direction: 'left'
}
}
})
簡寫方式
你可能想在 bind 和 update 時觸發(fā)相同行為,而不關(guān)心其它的鉤子。這應(yīng)該是項目中最常用的寫法
// xxx.vue
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
// js
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
})