1. 自定义指令基本用法
  2. 例子

自定义指令基本用法

自定义指令就像是之前使用的v-if,v-show等,本质上是解析一段表达式,并给当前元素绑定一个指令对象。和组件很像,也分为局部注册和全局注册,注册的函数是directive。

全局注册:

Vue.directive('focus',{})

局部注册:

var app = new Vue({
    el:"#app",
    directives:{
        focus:{

        }
    }
})

自定义指令有如下几个选项:

  1. bind,只调用一次,指令绑定到元素的时候调用。用来执行初始化动作。
  2. inserted,被绑定的元素插入父节点的时候调用,父节点存在即可调用,即使没有插入到DOM
  3. update,模板更新时候调用,注意是所在的模板更新,无论值更新与否
  4. componentUpdated,被绑定元素在完成一个更新周期时候调用
  5. unbind,解绑的时候调用

比如要实现元素插入父节点(未必显示)的时候就获得焦点,可以编写如下:

Vue.directive('focus',{
    inserted: function (el) {
        console.log(el);
        el.focus();
    }
});

var app = new Vue({
    el: "#app"
})

function的第一个参数,就是被绑定的对象本身。而且要注意自定义指令必须在一个Vue的实例范围内才能发生作用。

function的参数依次如下:

  1. el,被绑定的元素
  2. binding,一个对象,包含如下属性:
    1. name,指令名
    2. value,指令的绑定值
    3. oldValue,指令绑定的前一个值,只在update和componentUpdate钩子中可用
    4. expression,绑定的值的字符串形式
    5. arg,传给指令的参数。还记得v-bind:之后的冒号吗,这个冒号部分后边的内容就是传给指令的参数。
    6. modifiers,一个包含修饰符的对象,比如之前的事件修饰符等,是一个对象,存在修饰符就表示true。
  3. vnode,Vue编译生成的虚拟节点
  4. 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。

指令具体实现的功能,则都要使用函数的各个参数来进行操作。