Vue官方文档:https://cn.vuejs.org/v2/guide/custom-directive.html

什么是Vue自定义指令?

Vue自定义指令用起来就像Vue内置的v-modelv-on...之类,只不过实现了一些自己想要的功能。因为Vue自定义指令的钩子函数会传入一个el,它是自定义指令绑定到的那个DOM元素,所以Vue自定义指令可以用来直接和DOM打交道。

如何注册一个指令?

自定义指令分为全局和组件内的局部指令。全局自定义指令注册方法:

Vue.directive('myDirective', {
    // inserted是内置的钩子函数
    inserted: function (el) {
        // 一些操作...
    },
    // 指令的其他内容和钩子函数,如果需要的话...
})

组件内的局部指令注册方式:

new Vue({
    el: '#app',
    components: {
        'myComponent': {
            // 一些组件选项...
            directives: {
                myDirective: { /* 指令的内容和钩子函数 */ }
            }
            // 其他组件选项...
        },
    }
})

可能有像我一样的初学者(更可能就我自己)刚开始对new Vue({ ... components: {...} ... })export default {...}很疑惑,搞不清这两种东西是什么。后一种叫做单文件组件,链接在这:https://cn.vuejs.org/v2/guide/single-file-components.html,使用Vue-CLI,开发Vue程序,就默认用这种开发模式。在单文件组件模式中,初始化Vue往往放在src的根目录中的main.js中,包括app.vue也是一个组件。

自定义指令的每个钩子函数都会传入4个参数:
el:被绑定的元素,值如下(示例):'

'
binding:包含传入的各种参数,比如v-myDirective:1000="click",1000可以用binding.arg获取,'click'可以用binding.value获取。
vnodeoldVnode:这两个和虚拟DOM相关,请阅读Vue自定义指令和虚拟DOM的文档

实例:长按手势指令

下面定义一个长按手势指令,用来实现长按某一个元素,执行某些操作,比如弹出一个菜单。

longPress.js

export default {
    bind: function (el, binding) {
        if (typeof binding.value !== 'function') {
            return;
        }

        let timer = null;

        let start = (e) => {
            timer = setTimeout(function () {
                console.log('long press');
                timer = null;
            }, binding.arg? Number(binding.arg) : 1000);
        };

        let cancel = () => {
            if (timer !== null) {
                clearTimeout(timer);
                timer = null;
            }
        };

        el.addEventListener('touchstart', start);
        el.addEventListener('touchmove', cancel);
        el.addEventListener('touchend', cancel);
    }
}

使用这个指令的组件(单文件组件):

<template>
    <div class="item" v-longpress:4000="longPress"></div>
</template>

<script>
    import longpress from 'longPress.js';

    export default {
        directives: { longpress },
        methods: {
            longPress() {
                //console.log('longPress')
            }
        }
    }
</script>

这就完成了一个简单的自定义指令。在长按item元素4秒后,会在控制台打印"long press",并且会执行传入的函数longPress

标签: vue, Vue自定义指令