自定义指令 VUE基础回顾7
vue除了有v-if等内置指令,我们也可以创建自定义指令。
例:我们可以实现一个可以每隔一秒闪烁的节点,类似于<blink>标签的行为。添加一个指令类似于添加一个过滤器,可以将他传入vue实例或组件的directives属性,或者使用vue.directive()注册一个全局指令。传入指令的名字以及包含钩子函数的对象,这些钩子函数会在设置了该指令的元素的生命周期的各个阶段运行。
<div v-blink>闪烁的盒子</div>
5个钩子函数
bind:会在指令绑定到元素时被调用。
inserted:在被绑定的元素被添加到父节点时被调用。和mounted一样,并不能保证元素被添加DOM上。可以使用this.$nextTick保证
update: 节点被更新时调用,但是该组件的子组件可能还没有更新
componentUpdated: 更新完成后调用
unbind: 用于指令拆除,指令被解绑调用。
以上钩子函数不必每次都调用所有钩子,他们是可选的。bind和update钩子常用,如果想同时调用,可以传入一个函数作为参数,这个函数会分别被这两个
Vue.directive('test',(el)=>{ //代码会被 bind update 两个钩子调用 })
钩子函数参数
在前面已经回顾了指令可以接收参数,修饰符和值。可以传入钩子函数的第二个参数---binding---来访问这些所有内容,binding对象会包含以下属性
例:v-my:example.one.two="test"
name: 属性指令的名称,不包含v-。所以name的值为my
value: 传入指令的值。在这个例子中它将是test表达式的计算值。{test:hello world},那么value值就是hello word
oldValue: 属性上次传入得值,它只有子在update和componentUpdated中使用,如果改变test得值update被调用,此时得value得值是新的
expression: 指令表达式的字符串形式,之后会对该表达式求值。在这个例子中它的值为test
arg:传入指令的参数 也就是example
modifiers: 属性是一个包含所有传入指令的修饰符对象 也就是 one tow。
Vue.directive('blink',{ bind(el,binding){ let isVisible = true setInterval(()=>{ isVisible = !isVisible; el.style.visibility = isVisible ? 'visible' : 'hidden'; },binding.value || 1000) } })
上面的代码中添加了binding参数,并设置了计时时间。但是例子缺少了用于处理该指令值变化后更新组件的逻辑。要实现这一点需要将setInterval返回的ID存到元素的data属性上,然后再update钩子函数中清除旧定时器,之后再创建一个新的定时器。