自定义vue指令
- 注册一个全局指令:实现在document上注册注册全局点击事件
- 关于自定义指令的相关参数解析
一、注册一个全局指令
示例代码:
1 // 自定义指令: v-document-click(全局点击事件) 2 Vue.directive('document-click', { 3 bind: function (el, binding, vnode) { 4 if (document.addEventListener) { 5 document.addEventListener('click', binding.value, false) 6 } else if (document.attachEvent) { 7 document.attachEvent('onclick', function () { 8 binding.value.call(document) 9 }) 10 } 11 } 12 }) 13 14 //使用自定义全局点击事件指令 注册该事件 15 <div v-document-click="documentClick"> 16 17 // 18 methods:{ 19 documentClick(){ 20 .... 21 } 22 }
除了注册全局指令,也可以在局部的某个组件上创建指令:
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
这两种创建方式非常类是创建全局组件和局部组件的代码风格,但这不是重点,上面示例中并没有全部体现出创建指令的相关钩子函数和参数特性。
二、关于自定义指令的相关参数解析
2.1 自定义指令的参数
语法:
1 //InstructionName:指令名称 2 //params:自定义指令需要配置的相关参数 3 Vue.directive(InstructionName,params) 4 new Vue({ 5 data:{}, 6 ... 7 InstructionName:params 8 }); 9 //params:参数实际为既定的钩子函数,函数内部也会被传入既定的相关参数hookFunParams 10 { 11 hookFunction:function(hookFunParams){....} 12 .... 13 }
2.2 自定义指令的钩子函数(hookFunction)
bind:只调用一次、指令第一次绑定到元素是调用。
inserted:被绑定元素插入父节点时调用(但不确定是否插入到了文档中)。
update:所在组件的VNode更新时调用,但可能发生在其子VNode更新之前。
componentUpdated:指令所在组件的Vnode及其子VNode全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
2.2 自定义指令钩子函数的参数(hookFunParams)
el:指令所绑定的元素,可以用来直接操作的DOM。
binding:一个对象,包含一下property:
name:指令名称,不包括 v- 前缀。
value:指令绑定的值,例如: v-my-directive="1 + 1",绑定值为2。该值更多是一个函数,比如1.1中示例的v-document-click="documentClick",该documentClick是组件中methods注册的方法。
oldValue:指令绑定的前一个值,该属性仅在update和componentUpdated钩子函数中可用,无论值是否改变都可以用。
expression:字符串形式的指令表达式。例如1.1中的示例“documentClick”。
arg:传给指令的参数,可选。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 v-document-click:foo="documentClick" 2 3 data(){ 4 return { 5 foo:"text" 6 } 7 } 8 9 //在指令的钩子函数中就可以通过arg拿到foo的值了 10 console.log(binding.arg) // text
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为{foo:true, bar:true}。这个解和之前使用內置指令的修饰符来理解就很简单了,感觉解释起来还真的很麻烦。
vnode:Vue编译生成的虚拟节点,也就是指令绑定的元素对应的虚拟节点对象。
oldVnode:上一个虚拟节点,在更新指令所绑定的节点时,才会可以使用,所以只能在upate和componentUpdated两个狗子函数中才可以使用,要不然不更新哪里来的上一个。