简介
自定义指令就像一个迷你的函数,把你自定义的功能塞进这个迷你函数里,在页面上快速的调用,增加用户体验。
Vue.directive('dyColor',{
bind:function(el){
el.onclick = () => {
el.style.backgroundColor = '#' + Math.random().toString().slice(2,8)
}
}
})
new Vue({
el: '#app-1'
})
<div id="app-1">
<div class="box bg-fw" v-dy-color>
<h1>Lorem</h1>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Repellat beatae neque, quo, hic molestiae accusamus maxime cupiditate impedit quia labore aspernatur doloribus necessitatibus! Odio, quod eaque consectetur dolor asperiores id.</p>
</div>
</div>
上面这个简单示例中,使用Vue.directive('name',hooks)
定义一个指令,在页面上加上前缀v-
使用。bind()
为一个钩子函数,也有其他几种钩子,在钩子中完成一些自定义功能,钩子上有几个规定的参数,上面el
就是一个,钩子及参数后面分析。
钩子函数
总共有五种Hook,bind
、inserted
、update
、componentUpdated
及unbind
。
-
bind
: 在指令绑定到元素上时调用。 -
inserted
: 在被绑元素插入到父节点时调用一次(父节点是否插入文档无所谓) -
unbind
: 指令与元素解绑时调用一次。
inserted
是新版新加的,这个时机发生在bind
之后,增加点灵活度,就目前为止没发现有什么用。
-
update
:在被绑元素被修改时,修改内容未被插入时调用 -
componentUpdated
: 在被绑元素被修改并把修改内容插入后调用
官网这里是外星人写的,看不清,我暂时就这么理解了,这两个也是基于老版本update
修改的。把一个时间分成两部分而已。因为el
引用的一个是修改前、一个是修改后的内容,还是有点用。
Vue.directive('test', {
bind:function(el){
el.onclick = () => {
el.style.backgroundColor = '#' + Math.random().toString().slice(2,8)
}
$(el).find('#info_update').append('<li><span class="emblem">' + (el.parentNode?'有父元素':'无父元素') +'</span></li
console.log(el.parentNode)
console.log('bind')
},
inserted: function (el) {
$(el).find('#info_update').append('<li><span class="emblem">' + (el.parentNode?'有父元素':'无父元素') +'</span></li
console.log('inserted')
},
update: function (el) {
$(el).find('#info_update').append('<li><span class="emblem">' + $(el).find('h3').text() +'</span></li>')
console.log('update')
},
componentUpdated: function (el) {
$(el).find('#info_update').append('<li><span class="emblem">' + $(el).find('h3').text() +'</span></li>')
console.log('componentUpdated')
},
unbind: function (el) {
console.log('unbind')
}
})
new Vue({
el:'#app-2',
data:function(){
return {
msg:'test directive',
show:true
}
},
methods:{
updateData:function(){
this.msg = 'hello'
}
}
})
<script>
.emblem {
background-color: #f46;
color: #fff;
padding: 2px 4px;
font-size: 14px;
line-height: 15px;
height: 15px;
border-radius: 4px;
margin-top:5px;
display: inline-block;
}
</script>
<div id="app-2">
<button @click="updateData" class="btn btn-warn btn-sm">update</button>
<button @click="show = !show" class="btn btn-warn btn-sm">bind&Insert</button>
<button @click="show = !show" class="btn btn-warn btn-sm">unbind</button>
<div class="box" v-if="show" v-test>
<h3>{{msg}}</h3>
<p id="info_update">
</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Reprehenderit ad aut cupiditate.</p>
</div>
</div>
插入被绑元素时,可以看到bind
阶段的被绑元素没有父元素,而inserted
阶段是有的;而update
阶段使用的是修改前的数据,componentUpdated
阶段是使用后的数据,点击解绑按钮就是移除被绑元素,自然指令也和元素解绑了。
钩子函数参数
因为这几个参数,直接导致Vue灵活度*2,就像定义一个组件那样,自定义指令因为参数的开放性会有无限种可能。
-
el
:指令所绑定的元素,可以用来直接操作DOM -
binding
:一个对象,包含与指令本身相关的一些属性:-
name
:指令名,不包括v-前缀 -
value
:指令的绑定值,如例v-hello = "1 + 1"中,绑定值为2 -
expression
:字符串形式的指令表达式。例如v-hello = "1 + 1"中,表达式为"1 + 1" -
oldValue
:指令绑定的前一个值,仅在update和componentUpdated钩子中可用,无论值是否改变都可用 -
arg
:传给指令的参数,可选。例如v-hello:message中,参数为"message" -
modifiers
:一个包含修饰符的对象。例如v-hello.foo.bar中,修饰符对象为{foo:true, bar:true}
-
-
vnode
:Vue编译生成的虚拟节点。可以看成el
的底层表现,我们就可以通过它进一步去操作被绑元素 -
oldVnode
: 修改前的VNODE,仅在update和componentUpdated两个钩子函数中可用
一个有意义的示例不可能覆盖它们,在这里只能做个观察,后面写插件时尽量使用它们。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。