內容提要:
- 自定義指令基本用法介紹
- 自定義指令內部包含哪些鉤子函數
- 指令鉤子內部傳遞哪些元素值
- 自定義指令函數的縮略寫法用例
- 在JavaScript對象中傳遞多個字面值
介紹
除了在覈心附帶的默認的指令集合(v-model
和v-show
)外,Vue也允許你註冊自定義指令。注意在Vue 2.0,代碼重用和抽象的主要形式是組件-然而,可能某些情況下你可能需要針對原生元素進行一些底層的DOM訪問,這就是定製元素仍然有用的地方,一個例子是聚焦一個輸入框,像這樣:
當頁面加載的時候,元素獲得焦點(注意:autofocus
在手機的Safari上無效)。實際上,如果你訪問本頁後沒有點擊任何其他的地方,上面的輸入框應用獲得焦點。現在讓我們構建指令實現這個:
// 註冊一個全局的自定義指令稱爲“v-focus”
Vue.directive('focus', {
// 當綁定到元素插入到DOM時
inserted:function (el) {
// 焦點元素
el.focus()
}
})
如果你想註冊一個局部指令,組件頁接受directives
操作項:
direcitives: {
focus: {
// 指令定義
inserted: function (el) {
el.focus()
}
}
}
在模板內,你能在任何元素使用v-focus
屬性,像這樣:
<input v-focus>
鉤子函數
一個指令定義對象能夠提供一些鉤子函數(所有的都是可選):
-
bind
:僅被調用一次,當指令第一次綁定到元素時,在這裏,你可以做一些一次性設置工作 -
inserted
:當組件元素被插入到父節點的時候調用(這隻保證父節點的存在,不一定在文檔中)。 -
update
:包含組件的VNode被更新之後調用,但可能在它的子組件更新之前更新。指令的值可能改變也可能不變,但你能跳過不需要的更新通過對比當前的綁定值和舊值(參見下面的鉤子參數)。我們稍後later將更詳細的介紹VNodes,當我們渲染函數的時候 render functions。
-
componentUpdated
:包含組件的VNode和它的子組件的VNodes被更新之後調用。 -
unbind
: 僅僅被調用一次,當指令從元素解綁是調用。
通過這些鉤子我們可以查詢如下屬性(例如:el
,binding
,vnode
,和oldVnode
)在下一節。
指令鉤子元素
指令鉤子傳遞這些元素:
el
:指令綁定到的元素。這可以用來直接操作DOM。binding
:包含以下屬性的對象。name
:指令的名字,不帶v-
前綴value
:被傳遞給指令的值。例如在v-my-directive=“1 + 1”
,值是2
。oldValue
:舊值,僅在update
和componentUpdated
可用。無論值改變與否它都可用。expression
:作爲一個字符串綁定給表達式。例如在v-my-directive=“1 + 1”
,表達式是“1 + 1”
.arg
:傳遞給指令的參數(如果有的話),例如v-my-directive:foo
,參數是“foo”
。- 修飾符:包含修飾符的對象(如果有的話,例如在
v-my-directive.foo.bar
,修飾符對象是{ foo: true, bar: true }
.
vnode
: 通過Vue的編譯器產生的虛擬node。詳看 VNode API。oldVnode
:前一個虛擬node,僅在update
和componentUpdated
鉤子可用。
除了
el
之外,你要以只讀的方式對待這些參數,並且不要修改。如果你需要通過鉤子分享信息,我們建議你通過元素的dataset操作.
使用這些屬性的自定義指令的例子:
<div id="hook-arguments-example" v-demo: foo.a.b="message"></div>
Vue.directive('demo',{
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name:' + s(binding.name) + '<br>' +
'value:' + s(binding.value) + '<br>' +
'expression:' + s(binding.expression) + '<br>'
'argument:' + s(binding.arg) + '<br>' +
'modifiers:' + s(binding.modifiers) + '<br>' +
'vnode keys:' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
函數簡寫
許多情況下,你可能想讓bind
和update
有相同的行爲,但不關心其它的行爲,例如:
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
對象字面值
如果你的指令需要多個值,你也能夠在一個JavaScript對象的字面值中傳遞。記住,指令能攜帶任何有效的JavaScript表達式。
<div v-demo="{ color: 'white', text: 'hello!'}"></div>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => 'hello!'
})