關於自定義指令的寫法(全局和局部),有哪些鉤子函數,鉤子函數的參數這裏就不做講解,Vue文檔很清楚,可以直接看文檔的;https://cn.vuejs.org/v2/guide/custom-directive.html
一、 自定義雙向數據綁定
這個指令的實現還是比較簡單的;
- 首先在指令綁定到元素的時候,把數據和
data
中的數據保持一致;bind()
- 在
data
中的數據更新的時候,把更新過的數據更新到指令綁定的元素中;uodate()
- 在指令綁定的元素更新數據的時候,監聽
input
事件,通過event.target.value
拿到新的數據,更新到data
中去;inserted()
難點說明:(3.)
vnode.context[binding.expression]
vnode
:Vue 編譯生成的虛擬節點,其實就是組件的虛擬 DOM 對象
vnode.context
: 指令綁定的元素所在的組件的對象
binding.expression
:字符串形式的指令表達式( v-gx="gong"
中的 gong
)
鉤子函數的參數 – vnode
vnode
:使用了指令之後,它會把當前這個元素,創建成一個虛擬的 DOM元素;
裏邊包含(常用):
- context:這個指令綁定的元素所在的組件對象;
- data:綁定指令的數據;
- elm:指令所綁定的真實 DOM元素;
主要代碼
<div id="app">
<input type="text" v-sync='name'>
<input type="text" v-model="name" style="background-color: #ccc;">
</div>
<script>
Vue.directive('sync',{
bind(el, binding, vnode){
el.value = binding.value;
},
inserted(el, binding, vnode){
el.addEventListener('input', (ev)=>{
vnode.context[binding.expression] = ev.target.value;
});
},
update(el, binding, vnode){
el.value = binding.value;
}
});
new Vue({
el: '#app',
data: {
name: '宮鑫'
}
})
</script>
二、自定義事件指令
要實現這個事件的自定義指令,其實主要是靈活運用鉤子函數的參數 binding
,主要是如下幾個參數
binding.arg
:傳給指令的參數,可選。例如 v-my-directive:foo
中,參數爲 “foo
”。
binding.value
:指令的綁定值,例如:v-my-directive="1 + 1"
中,綁定值爲 2
。
binding.modifiers
:一個包含修飾符的對象。例如:v-my-directive.foo.bar
中,修飾符對象爲{ foo: true, bar: true }
。
再加上一些判斷,自定義事件指令就完成了;
主要代碼
<div id="app">
<button v-gx:click.stop="run">按鈕</button>
</div>
<script>
Vue.directive('gx', {
bind(el, binding, vnode) {
// 【1】判斷值是不是一個函數
if (typeof binding.value == 'function') {
// 【2】判斷事件類型是否符合
if (/(click|mouseover|mouseout|mousemove|keydown|keyup)/.test(binding.arg)) {
// 【3】給指令綁定的元素綁定事件
el.addEventListener(binding.arg, (ev) => {
// 【4】修飾符 比如:stop
if (binding.modifiers.stop) {
ev.stopPropagation();
}
// 【5】執行函數
binding.value(ev)
});
} else {
console.error('您的事件類型有誤,請檢查:' + binding.arg);
}
} else {
console.error('您傳入的值並不是一個函數:' + binding.value);
}
}
});
new Vue({
el: '#app',
methods: {
run(val) {
alert(val);
}
},
})
</script>
衣帶漸寬終不悔,爲伊消得人憔悴