Vue自訂指令可以在全域或局部定義,Vue元件是html和程式碼的複用,而Vue指令是對DOM的擴充復用;下面我們就來具體看看Vue中自訂指令的分析。
1、Vue自訂指令:使用Vue.directive(id,definition)註冊全域自訂指令,使用元件的directives選項註冊局部自訂指令。
2、Vue 鉤子函數:
指令定義函數提供了幾個鉤子函數(可選):
bind:只呼叫一次,指令第一次綁定到元素時調用,用這個鉤子函數可以定義一個在綁定時執行一次的初始化動作。
inserted:被綁定元素插入父節點時調用(父節點存在即可調用,不必存在於 document 中)。
update:第一次是緊跟在 bind 之後調用,獲得的參數是綁定的初始值,之後被綁定元素所在的模板更新時調用,而不論綁定值是否變化。透過比較更新前後的綁定值,可以忽略不必要的模板更新(詳細的鉤子函數參數見下)。
componentUpdated:被綁定元素所在模板完成一次更新週期時呼叫。
unbind:只呼叫一次, 指令與元素解綁時呼叫。
3、Vue 鉤子函數的參數:(el, binding, vnode, oldVnode)
el:指令所綁定的元素,可以用來直接操作 DOM 。
binding:一個對象,包含以下屬性
## name:指令名,不包含v-的前綴; value:指令的綁定值;例如:v- my-directive="1 1",value的值是2; oldValue:指令綁定的前一個值,僅在update和componentUpdated鉤子函數中可用,無論值是否改變都可用; expression:綁定值的字串形式;例如:v-my-directive="1 1",expression的值是'1 1';## arg:傳給指令的參數;例如:v-my-directive:foo,arg的值為'foo';
modifiers:一個包含修飾符的物件;例如:v-my-directive.a.b,modifiers的值為{'a ':true,'b':true}
vnode:Vue編譯的產生虛擬節點;
oldVnode:上一次的虛擬節點,僅在update和componentUpdated鉤子函式中可用。
<p id="app" v-demo:foo.a.b="message"></p> Vue.directive('demo', { bind: function (el, binding, vnode) { console.log('bind'); 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: '#app', data: { message: 'hello!' } });
4、函數簡寫:大多數情況下,我們可能想在 bind 和 update 鉤子上做重複動作,並且不想關心其它的鉤子函數。可以這樣寫:
Vue.directive('color-swatch', function (el, binding) { el.style.backgroundColor = binding.value })
5、物件字面量:如果指令需要多個值,可以傳入一個 JavaScript 物件字面量。記住,指令函數能夠接受所有合法類型的 Javascript 表達式。
<p v-demo="{ color: 'white', text: 'hello!' }"></p> Vue.directive('demo', function (el, binding) { console.log(binding.value.color) // => "white" console.log(binding.value.text) // => "hello!" })
範例解析:
<p id="app"> <my-comp v-if="msg" :msg="msg"></my-comp> <button @click="update">更新</button> <button @click="uninstall">卸载</button> <button @click="install">安装</button> </p> <script type="text/javascript"> Vue.directive('hello', { bind: function (el){ console.log('bind'); }, inserted: function (el){ console.log('inserted'); }, update: function (el){ console.log('update'); }, componentUpdated: function (el){ console.log('componentUpdated'); }, unbind: function (el){ console.log('unbind'); } }); var myComp = { template: '<h1 v-hello>{{msg}}</h1>', props: { msg: String } } new Vue({ el: '#app', data: { msg: 'Hello' }, components: { myComp: myComp }, methods: { update: function (){ this.msg = 'Hi'; }, uninstall: function (){ this.msg = ''; }, install: function (){ this.msg = 'Hello'; } } }) </script>
a、頁面載入時:bind inserted
b、更新元件:update componentUpdated
c、卸載元件:unbind
d、重新安裝元件:bind inserted
注意區別:bind與inserted:bind時父節點為null,inserted時父節點存在;update與componentUpdated:update是資料更新前, componentUpdated是資料更新後。
6.最後上一個實際開發的指令封裝實作
#基本想法
import store from '@/store' export default { inserted(el, binding, vnode) { const { value } = binding const roles = store.state.permission.pagePermission if (value && typeof value === 'string' && value.length > 0) { const hasPermission = roles.some(role => { return role.permission == value }) if (!hasPermission) { el.parentNode && el.parentNode.removeChild(el) } } else { throw new Error(`need roles! Like v-permission="'button'"`) } } }
向外暴露api
import permission from './permission' const install = function(Vue) { Vue.directive('permission', permission) } if (window.Vue) { window['permission'] = permission Vue.use(install) // eslint-disable-line } permission.install = install export default permission
相關推薦:
vue自訂指令實作v-tap外掛怎麼使用Vue的自訂指令完成一個下拉式選單以上是Vue自訂指令及指令定義函數的具體分析(程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!