Vue 自定义指令

关于自定义指令的写法(全局和局部),有哪些钩子函数,钩子函数的参数这里就不做讲解,Vue文档很清楚,可以直接看文档的;https://cn.vuejs.org/v2/guide/custom-directive.html

一、 自定义双向数据绑定

这个指令的实现还是比较简单的;

  1. 首先在指令绑定到元素的时候,把数据和 data 中的数据保持一致; bind()
  2. data 中的数据更新的时候,把更新过的数据更新到指令绑定的元素中; uodate()
  3. 在指令绑定的元素更新数据的时候,监听 input 事件,通过 event.target.value 拿到新的数据,更新到 data 中去;inserted()

难点说明:(3.)
vnode.context[binding.expression]
vnode:Vue 编译生成的虚拟节点,其实就是组件的虚拟 DOM 对象
vnode.context指令绑定的元素所在的组件的对象
binding.expression:字符串形式的指令表达式( v-gx="gong" 中的 gong

钩子函数的参数 – vnode
vnode:使用了指令之后,它会把当前这个元素,创建成一个虚拟的 DOM元素;
里边包含(常用):

  1. context:这个指令绑定的元素所在的组件对象;
  2. data:绑定指令的数据;
  3. elm:指令所绑定的真实 DOM元素;

主要代码

<div id="app">
    <input type="text" v-sync='name'>
    <input type="text" v-model="name" style="background-color: #ccc;">
div>

<script>
    Vue.directive('sync',{
        bind(el, binding, vnode){
            el.value = binding.value;
        },
        inserted(el, binding, vnode){
            el.addEventListener('input', (ev)=>{
                vnode.context[binding.expression] = ev.target.value;
            });
        },
        update(el, binding, vnode){
            el.value = binding.value;
        }
    });

    new Vue({
        el: '#app',
        data: {
            name: '宫鑫'
        }
    })
script>

二、自定义事件指令

要实现这个事件的自定义指令,其实主要是灵活运用钩子函数的参数 binding,主要是如下几个参数
binding.arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
binding.value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
binding.modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为{ foo: true, bar: true }
再加上一些判断,自定义事件指令就完成了;

主要代码

<div id="app">
    <button v-gx:click.stop="run">按钮button>
div>

<script>
    Vue.directive('gx', {
        bind(el, binding, vnode) {
            // 【1】判断值是不是一个函数
            if (typeof binding.value == 'function') {
                // 【2】判断事件类型是否符合
                if (/(click|mouseover|mouseout|mousemove|keydown|keyup)/.test(binding.arg)) {
                    // 【3】给指令绑定的元素绑定事件
                    el.addEventListener(binding.arg, (ev) => {
                        // 【4】修饰符 比如:stop
                        if (binding.modifiers.stop) {
                            ev.stopPropagation();
                        }
                        // 【5】执行函数
                        binding.value(ev)
                    });
                } else {
                    console.error('您的事件类型有误,请检查:' + binding.arg);
                }
            } else {
                console.error('您传入的值并不是一个函数:' + binding.value);
            }

        }
    });

    new Vue({
        el: '#app',
        methods: {
            run(val) {
                alert(val);
            }
        },
    })
script>




衣带渐宽终不悔,为伊消得人憔悴

你可能感兴趣的:(前端开发)