自定义指令基本用法
自定义指令就像是之前使用的v-if,v-show等,本质上是解析一段表达式,并给当前元素绑定一个指令对象。和组件很像,也分为局部注册和全局注册,注册的函数是directive。
全局注册:
Vue.directive('focus',{})
局部注册:
var app = new Vue({ el:"#app", directives:{ focus:{ } } })
自定义指令有如下几个选项:
bind
,只调用一次,指令绑定到元素的时候调用。用来执行初始化动作。inserted
,被绑定的元素插入父节点的时候调用,父节点存在即可调用,即使没有插入到DOMupdate
,模板更新时候调用,注意是所在的模板更新,无论值更新与否componentUpdated
,被绑定元素在完成一个更新周期时候调用unbind
,解绑的时候调用
比如要实现元素插入父节点(未必显示)的时候就获得焦点,可以编写如下:
Vue.directive('focus',{ inserted: function (el) { console.log(el); el.focus(); } }); var app = new Vue({ el: "#app" })
function的第一个参数,就是被绑定的对象本身。而且要注意自定义指令必须在一个Vue的实例范围内才能发生作用。
function的参数依次如下:
el
,被绑定的元素binding
,一个对象,包含如下属性:name
,指令名value
,指令的绑定值oldValue
,指令绑定的前一个值,只在update和componentUpdate钩子中可用expression
,绑定的值的字符串形式arg
,传给指令的参数。还记得v-bind:之后的冒号吗,这个冒号部分后边的内容就是传给指令的参数。modifiers
,一个包含修饰符的对象,比如之前的事件修饰符等,是一个对象,存在修饰符就表示true。
vnode
,Vue编译生成的虚拟节点oldVnode
,上一个虚拟节点,只在update和componentUpdate钩子中可以使用。
看到了上边的这些内容,就会知道指令也没有什么奇特的,以前使用的v-bind是带参数的指令,v-on是有绑定值和修饰符的指令。有了这些东西,就可以自行编写指令来实现各种效果了。
这里用的比较多的,是绑定值和参数。
参数其实就是一个字符串,虽然之前的内部属性很多时候看上去绑定了HTML标签的属性,但其实在Vue内部,就是字符串,所以可以用来当做标签属性的名称,在最后渲染的时候生效。
而绑定的值从binding对象也能看出来,有绑定值(经过JS解析)和绑定的值的字符串形式两种内容。所以在绑定值的时候也可以传一个JS能够解析的字符串比如对象。
例子
我个人的理解,所有的“自定义”,其实都是为了满足特定的需求,然而也会带来更高的耦合程度。如果说Vue实例绑定了一个区域用于控制,自定义指令实际上绑定了一个具体元素,确实大大提高了灵活性。通过一个指令就可以让一个元素化身为一个具体特定功能的区域。
例子其实要举就太多了,还是就简单遍历一个自定义指令的所有内容吧:
<div id="app"> <div v-test:msg.a.b='{name:"jenny"}'></div> </div> <script> Vue.directive('test',{ bind: function (el, binding, vnode) { console.log(el); var keys = []; for (var i in vnode) { keys.push(i) } el.innerHTML = 'name:' + binding.name + '<br>' + 'value:' + binding.value + '<br>' + 'expression:' + binding.expression + '<br>' + 'argument:' + binding.arg + '<br>' + 'modifiers:' + JSON.stringify(binding.modifiers) + '<br>' + '<hr>' + 'vnodekeys:' + keys.join('<br>'); } }); new Vue({ el: "#app", data:{ // message:"saner" } }) </script>
用了一个带有参数,绑定元素,绑定解析内容的指令,基本上把前边的都用全了。这其中尤其需要关注的就是value,expression和argument。
指令具体实现的功能,则都要使用函数的各个参数来进行操作。