基礎簡介
除了核心功能默認的內置指令(v-model和v-show),vue也允許註冊自定義指令。注意,在Vue2.0中,代碼複用和抽象的主要形式是組件,但是在有些情況下,我們需要對普通的DOM元素進行底層操作,這時候就需要我們用到自定義指令。
簡單事例,當頁面加載時元素就會獲得焦點,但是實際上只要我們代碼完成,頁面沒打開時這個輸入框已經是聚焦狀態:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="Vue.min.js"></script>
</head>
<body>
<div id="app">
<input v-focus>
</div>
<script>
//註冊一個全局自定義指令v-focus
Vue.directive('focus', {
// 當綁定元素插入到DOM中
inserted: function (el) {
// 聚焦元素
el.focus()
}
});
var app = new Vue({
el: '#app'
});
</script>
</body>
</html>
鉤子函數
我們可以使用Vue.directive的方法傳入執行id和定義對象來註冊一個全局的自定義指令,一個指令對象可以提供幾個鉤子函數:
- bind:只調用一次,指令第一次綁定元素的時候調用,這時我們可以進行對它的一次性初始化設置。
- inserted,被綁定元素插入父節點時的調用。
- update,所在組件的 VNode 更新時調用,但是可能發生在組件的 VNode更新前,因此指令的值是不確定的,可能有也可能沒有。
- componentUpdated,指令所在組件的 VNode以及它之後的更新調用。
- unbind,只調用一次,指令與元素解綁時調用。
定義對象的鉤子函數參數有(除了el之外其他參數都是隻讀的):
- el:指令綁定的元素,可以被用來直接操作DOM。
-
binding
- name:指令名,不包括 v- 前綴。
- value:指令的綁定值,例如:v-new-xkd:"1+2";,綁定值爲3。
- oldValue:指令綁定的前一個值,只在update 和 componentUpdated 鉤子中使用。
- expression:字符串形式的指令表達式。例如上面 v-new-xkd中的"1+2"。
- arg:傳給指令的參數。
- modifiers:一個包含修飾符的對象。
- vnode:Vue 編譯生成的虛擬節點。
- oldVnode:上一個虛擬節點。
指令的參數可以是動態的。
自定義鉤子函數屬性事例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="Vue.min.js"></script>
</head>
<body>
<div id="hook" v-xkd:foo.a.b="message"></div>
<script>
// 使用自定義指令
Vue.directive('xkd', {
// 指令在綁定到元素要執行的操作
bind: function (el, binding, vnode) {
var w = JSON.stringify;
// 準備將傳遞來的參數顯示在調用該指令的元素的innerHTML上
el.innerHTML =
'name: ' + w(binding.name) + '<br><br>' +
'value: ' + w(binding.value) + '<br><br>' +
'expression: ' + w(binding.expression) + '<br><br>' +
'argument: ' + w(binding.arg) + '<br><br>' +
'modifiers: ' + w(binding.modifiers) + '<br><br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
// 創建自定義指令
new Vue({
el: '#hook',
data: {
message: '俠課島'
}
})
</script>
</body>
</html>
函數簡寫
大多數情況下,可能想在bind和update鉤子上做重複動作,並且不想關心其它的鉤子函數,可以這樣寫:
Vue.directive('func-abbr', function (el, binding) {
el.style.backgroundColor = binding.value
})
對象字面量
如果指令需要多個值,那麼可以傳入一個JavaScript對象字面量;同一個特性內部,逗號隔開的多個從句被綁定爲多個指令實例。
<div id="hook" v-demo="{ color: 'green', text: 'Chivalrous Island!'}"></div>
<script>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color);
console.log(binding.value.text);
})
// 創建自定義指令
new Vue({
el: '#hook',
data: {
message: '俠課島'
}
})
</script>