关于自定义指令的写法(全局和局部),有哪些钩子函数,钩子函数的参数这里就不做讲解,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>
衣带渐宽终不悔,为伊消得人憔悴