除了核心功能默认内置的指令 (v-model 和 v-show)
,Vue 也允许注册自定义指令
。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
可以说组件是对UI层的复用,自定义指令是控制层与行为层的复用
自定义指令和组件注册的方法很相似,也分为全局注册和局部注册。
全局注册指令(和全局注册一样)
把全局注册时的component单词换成directive即可
Vue.directive("指令名",{
//指令内容
})
局部注册指令(和局部注册一样)
在vue或者组件实例中添加directives选项即可
//vue实例
let vueApp = new Vue({
el: "#app",
directives: {
dire1: {}, //声明指令dire1
dire2: {}, //声明指令dire2
dire3: {}, //声明指令dire3
}
});
概念
和组件具有生命周期钩子函数一样,指令也具有生命周期钩子函数,你可以在不同的钩子函数里面进行不同的操作。比如:在指令与元素绑定时执行什么,在指令与元素解绑时又执行什么。
具体的钩子函数(指令的生命周期内)
1.bind: 指令第一次绑定到元素上时执行,在这里可以进行一次性的初始化设置。
2.inserted: 被绑定元素插入父节点时调用,(父节点存在即可调用,不一定已被插入文档中)
3.update : 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。此时指令绑定的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
4.componentUpdated: 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
5.unbind: 只绑定一次,指令与元素解绑时调用
注意
这些钩子函数在指令实现中都是可选的,并不是一定都要给上,然后我们的指令实现代码一般都是放在这些钩子函数中进行执行。
注意:
1.在自定义指令使用时会加上v-前缀,表示是vue的自定义指令,但是在我们定义时不需要加上
2.自定义指令名称合法即可
3.你的指令实现代码写到那个构造函数中,那么就会在其对应时刻执行
//指令内容:将实现写在inserted钩子函数中,表示input插入到了父节点就自动聚焦
inserted: function (el) {
el.focus(); //自定获取焦点
}
Document
前面我们看到了,在inserted构造函数中接受了一个参数el, 他表示当前指令绑定的元素。实际上还有其他参数。
然后由于我们的所有代码都是写在各个构造函数里面的,所以我们必须明白钩子函数的几个参数。
参数详情
大致有四个参数: el , binding , vnode , oldVnode.
这几个参数是对位传参,根据位置来判断,命名合法就行。
1.el: 表示指令所绑定的元素,可用来直接操作DOM
2.binging: 一个绑定对象,主要的属性如下:
binding = {
name: "指令名。这是你定义时的名字",
rawName: "指令实际使用时的名字",
expression: "指令绑定的表达式名称",
value: "指令绑定的表达式的真正的值,即expresion这个表达式对应的值",
modifiers: "指令在使用时如果添加了修饰符的话,这就表示修饰符集合对象,比如stop"
oldValue: "指令绑定的表达式的上一个值,仅在update和componentUpdate钩子中可用",
arg: "传给指令的参数。例如,对与v-on:click=”fn”而言,click就是参数",
}
这些属性并不是在每一个钩子函数的binging参数里都有,要看实际使用时是否含有值。
3.Vnode: vue编译生成的虚拟节点,后面介绍
4.oldVnode: 上一个虚拟节点,仅在update和componentUpdate钩子中可用
注意
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。(直接放到el元素对象上)
在很多时候,你可能想在 bind
和 update
时触发相同行为,而不关心其它的钩子。比如这样写:
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
实例:下面两种方式实现效果是一样的,但是第二种会在 bind
和 update
时都触发
如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。
这意味着我们可以通过,指令绑定的表达式值与值不同做出不同的响应
这里绑定的是对象字面量(也可以直接绑定vue实例对象中的数据)