Vue.js: 自定義指令 Custom Directive
05 May 2017Vue.js 提供自定義指令讓開發者直接從底層操作 DOM 物件。
如下,將價格加上千分位符號。
當指令v-price
綁定到 DOM element 上並傳入參數 123456789 時,轉成使用逗點分隔的 123,456,789。
程式碼。
<div id="app">
<span id="number" v-price:currency="dollar"></span>
</div>
Vue.directive('price', {
bind: function (el, binding) {
el.innerHTML = binding.value.toString().replace(/^(-?\d+?)((?:\d{3})+)(?=\.\d+$|$)/, function (all, pre, groupOf3Digital) {
return pre + groupOf3Digital.replace(/\d{3}/g, ',$&');
});
}
});
var vm = new Vue({
el: '#app',
data: {
dollar: 123456789
}
});
Demo。
自定義指令的部份可簡化為
Vue.directive('price', function (el, binding) {
el.innerHTML = binding.value.toString().replace(/^(-?\d+?)((?:\d{3})+)(?=\.\d+$|$)/, function (all, pre, groupOf3Digital) {
return pre + groupOf3Digital.replace(/\d{3}/g, ',$&');
});
});
這個定義方法稱為全域註冊,也可使用局部註冊,即在元件 (component) 中撰寫自定義指令。
鉤子函數 (Hook Functions)
自定義指令提供了數個鉤子函數,讓我們能使用 callback 在綁定元素的生命週期的不同階段做些事情。
- bind:發生時機點為指令第一次綁定到元素上時,因此只會使用一次。常用於初始化。如上例,在指令第一次綁定到
<span id="number">
時將價格加上千分位符號。 - inserted:綁定元素插入父節點時使用。
- update:綁定元素在模版更新時使用。
- componentUpdated:綁定元素在元件更新時使用。
- unbind:解除指令與元素的綁定。
鉤子函數的參數 (Directive Hook Arguments)
分述 el、binding、vnode 與 oldVnode 如下,最後有範例說明。
el
自定義指令所綁定的元素,也就是想要操作的 DOM 物件,如上例,<span id="number">
。
binding
binding 物件包含一些屬性
- name:自定義指令名,不含前綴「v-」,如下例的「say」。
- value:指令的綁定值,如下例的「
{"name":"Peter","prompt":"Hello World"}
」。 - oldValue:綁定值的前一個值,儘在 update 或 componentUpdated 時可用。
- expression:綁定值的字串,如上例的「dollar」、下例的「
{"name":"Peter","prompt":"Hello World"}
」。 - arg:傳給自定義指令的參數,如上例的「currency」、下例的「hello」。
- modifiers:修飾符,如下例的「a」、「b」、「c」。如果不知道修飾符是什麼,可參考事件修飾符 (Event Modifiers)。
如果需要傳入多個參數,可用物件的方式傳入。如下例的「{"name":"Peter","prompt":"Hello World"}
」。
vnode
虛擬節點 (virtual DOM)。
oldVnode
前一個虛擬節點,儘在 update 或 componentUpdated 時可用。
範例
將鉤子函數的參數印出來。
程式碼。
<div id="app">
<span v-say:hello.a.b.c="{ name: 'Peter', prompt: message }"></span>
</div>
Vue.directive('say', {
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(', ');
}
});
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World'
}
});
Demo。
以上參考自 Custom Directives。