1.Vue有豐富的內(nèi)置指令,在需要一些特殊功能時皿渗,我們?nèi)韵M麑OM進行底層的操作,這時就要用到自定義指令没卸。
2.自定義指令的注冊方法和組件很像羹奉,也分全局注冊和局部注冊,比如注冊一個v-focus的指令约计,用于在<input>诀拭、<textarea>元素初始化時自動獲得焦點,兩種寫法分別是:
//全局注冊
Vue.directive('focus',{
//指令選項
})
//局部注冊
var app = new Vue({
el:'#app',
directives:{
focus:{
//指令選項
}
}
})
寫法與組件基本類似煤蚌,只是方法名由component改為了directive耕挨。
上例只是注冊了自定義指令v-focus,還沒有實現(xiàn)具體功能尉桩。
3.自定義指令的各個選項都是由幾個鉤子函數(shù)組成的筒占,每個都是可選的。
- bind:只調(diào)用一次蜘犁,指令第一次綁定到元素時調(diào)用翰苫,用這個鉤子函數(shù)可以定義一個綁定時執(zhí)行一次的初始化動作。
- inserted:被綁定元素插入父節(jié)點時調(diào)用(父節(jié)點存在即可調(diào)用这橙,不必存在于document中)
- update:被綁定元素所在的模板更新時調(diào)用奏窑,而不論綁定值是否變化。通過比較更新前后的綁定值屈扎,可以忽略不必要的模板更新埃唯。
- componentUpdated:被綁定元素所在模板完成一次更新周期時調(diào)用。
- unbind:只調(diào)用一次鹰晨,指令與元素解綁時調(diào)用墨叛。
4.可以根據(jù)需求在不同的鉤子函數(shù)內(nèi)完成邏輯代碼止毕,例如上面的v-focus,我們希望在元素插入父節(jié)點時就調(diào)用漠趁,那用到的最好是inserted扁凛。示例:
<div id="app">
<input type="text" v-focus>
</div>
<script>
//全局注冊
Vue.directive('focus',{
//指令選項
inserted:function(el){
//聚焦元素
el.focus();
}
})
//局部注冊
var app = new Vue({
el:'#app'
})
</script>
可以看到,打開這個頁面棚潦,input輸入框就自動獲得了焦點令漂,成為可輸入狀態(tài)。
5.每個鉤子函數(shù)都有幾個參數(shù)可用丸边,比如上面我們用到了el叠必。它們的含義如下:
- el 指令所綁定的元素,可以用來直接操作DOM妹窖。
- binding 一個對象纬朝,包含以下屬性:
name :指令名,不包括 v-前綴骄呼。
value :指令的綁定值共苛,例如 v-my-directive="1+1" ,value的值是2蜓萄。
oldValue :指令綁定的前一個值隅茎,僅在update 和 componentUpdated 鉤子中可用。無論值是否改變都可用嫉沽。
expression :綁定至的字符串形式辟犀。例如 v-my-directive="1+1",expredsion的值是 "1+1"绸硕。
arg:傳給指令的參數(shù)堂竟。例如 v-my-directive:foo,arg的值是foo玻佩。
modifiers :一個包含修飾符的對象出嘹。例如 v-my-directive.foo.bar,修飾符對象modifiers的值是{ foo:true , bar: true}咬崔。
vnode :Vue編譯生成的虛擬節(jié)點税稼,后續(xù)介紹。
oldVnode :上一個虛擬節(jié)點僅在update 和 componentUpdate鉤子中可用垮斯。
下面是結(jié)合了以上參數(shù)的一個示例:
<div id="app">
<div v-test:msg.a.b="message"></div>
</div>
<script>
Vue.directive('test',{
bind:function(el,binding,vnode){
var keys = [];
for(var i in vnode){
keys.push(i)
}
el.innerHTML =
'name:' + binding.name + '<br>' +
'value:' + binding.value + '<br>' +
'expression:' + binding.expression + '<br>' +
'argument:' + binding.arg + '<br>' +
'modifiers:' + JSON.stringify(binding.modifiers) + '<br>' +
'vnode keys:' + keys.join(',')
}
});
//局部注冊
var app = new Vue({
el:'#app',
data:{
message:'some text'
}
})
</script>
在大多數(shù)使用場景郎仆,我們會在 bind 鉤子里綁定一些事件,比如在document上用 addEventListener綁定甚脉,在unbind里用 removeEventListener 解綁,比較典型的示例就是讓這個元素隨著鼠標拖拽铆农。如果需要多個值牺氨,自定義指令可以傳入一個JavaScript對象字面量狡耻,只要是合法類型的JavaScript表達式都是可以的。示例:
<div id="app">
<div v-test="{msg:'hello',name:'Aresn'}"></div>
</div>
<script>
Vue.directive('test',{
bind:function(el,binding,vnode){
console.log(binding.value.msg)
console.log(binding.value.name)
}
});
//局部注冊
var app = new Vue({
el:'#app'
})
</script>
Vue2.x移除了大量Vue 1.x自定義指令的配置猴凹。
在使用自定義指令時夷狰,應(yīng)該充分理解業(yè)務(wù)需求,因為很多時候你需要的可能并不是自定義指令郊霎,而是組件沼头。后續(xù)的實戰(zhàn)示例可以進一步了解自定義指令的使用場景和用法。