【Vue】Vue自定义指令基础全面详解

本文介绍Vue自定义指令基础,采用注册一个v-color的指令,给字体赋值颜色为例子。

一、全局注册

Vue.directive('color', {
    inserted: function (el,binding) {
        el.style.color=binding.value;
    }
})

使用

<template>
    <div>
        <h1 v-color="color">自定义指令</h1>
    </div>
</template>
<script>
export default {
    data() {
        return {
            color:'red'
        }
    },
}
</script>

渲染结果

【Vue】Vue自定义指令基础全面详解

二、局部注册

<template>
    <div>
        <h1 v-color="color">自定义指令</h1>
    </div>
</template>
<script>
export default {
    data() {
        return {
            color:'red'
        }
    },
    directives:{
        color:{
            inserted:function(el,binding){
                el.style.color=binding.value;
            }
        }
    }
}
</script>

三 自定义指令的钩子函数

从上面的例子的可以看到inserted的选项,这个就是自定义指令的钩子函数,自定义指令有五个钩子函数:

  1. bind:只调用一次,在指令第一次绑定到元素时调用,可以在这个钩子函数中进行初始化设置;
  2. inserted:被绑定元素插入父节点时调用,在bind后面调用;
  3. update:所在绑定的组件的VNode更新时调用,但是可能发生在其子VNode更新之前。 调用时指令的值不一定发生改变,通过比较更新前后的值来忽略不必要的模板更新;
  4. componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用;
  5. unbind:只调用一次,指令与元素解绑时调用。
Vue.directive('color', {
    bind:function(){
        alert('bind')
    },
    inserted: function (el,binding) {
        alert('inserted')
        el.style.color=binding.value;
    },
    update:function(el,binding){
        alert('update')
        el.style.color=binding.value;
    },
    componentUpdated:function(el,binding){
        alert('componentUpdated')
        el.style.color=binding.value;
    },
    unbind:function(){
       alert('v-color指令解绑')
    }
})
<template>
    <div>
        <h1 v-color="color" v-if="show">{{title}}</h1>
        <button @click="show=false">测试解绑v-color</button>
        <button @click="title='更换title'">更换title</button>
        <button @click="color='blue'">更换color</button>
    </div>
</template>
<script>
export default {
    data() {
        return {
            color: 'red',
            title: '自定义指令',
            show: true
        }
    },
}
</script>

四、钩子函数的参数

从上面的例子的可以看到inserted的选项的值是个Funcion,其中el binding就是钩子函数的参数,其有4个参数:

  1. el:指令所绑定的元素,可以用来直接操作DOM;

  2. binding:一个对象其中包括以下几个属性;

    • name:指令名,不包括 v- 前缀;
    • value:指令的绑定值,例:v-my-directive="1 + 1"中,绑定值为 2;
    • expression:指令的绑定的表达式。例:v-my-directive="1 + 1"中,表达式为 "1 + 1";
    • arg:传给指令的参数,例v-my-directive:foo中,参数为 "foo";
    • modifiers:一个包含修饰符的对象。例:v-my-directive.foo.bar中,修饰符对象为 { foo: true, bar: true },
    • oldValue:指令绑定的前一个值,仅在updatecomponentUpdated钩子中可用。无论值是否改变都可用。
  3. vnode:Vue 编译生成的虚拟节点;

  4. oldVnode:上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。

除了el之外,其它参数都是只读的,不能对其修改。如果需要在钩子之间共享数据,要通过元素的dataset来进行。

五、注册一个让字体颜色闪烁的指令v-color

本例采用元素的dataset在不同的钩子函数中控制setInterval

采用动态指令参数来控制字体颜色闪烁频率。

Vue.directive('color', {
    inserted: function (el, binding) {
        const interval = binding.arg ? binding.arg : 1000;
        if (Array.isArray(binding.value)) {
            let i = 0;
            el.style.color = binding.value[i];
            el.dataset.time = setInterval(() => {
                if (i > binding.value.length - 1) {
                    i = 0;
                }
                el.style.color = binding.value[i];
                i++;
            }, interval);
        } else {
            el.style.color = binding.value;
        }
    },
    componentUpdated: function (el, binding) {
        clearInterval(el.dataset.time);
        const interval = binding.arg ? binding.arg : 1000;
        if (Array.isArray(binding.value)) {
            let i = 0;
            el.style.color = binding.value[i];
            el.dataset.time = setInterval(() => {
                if (i > binding.value.length - 1) {
                    i = 0;
                }
                el.style.color = binding.value[i];
                i++;
            }, interval);
        } else {
            el.style.color = binding.value;
        }
    },
    unbind: function (el, binding) {
        clearInterval(el.dataset.time)
    }
})
<template>
    <div>
        <h1 v-color:[interval]="color">自定义指令</h1>
        <button @click="interval+=100">慢点闪</button>
        <button @click="interval-=100">快点闪</button>
    </div>
</template>
<script>
export default {
    data() {
        return {
            color: ['red','blue','green','yellow','Pink','purple'],
            interval:1000,
        }
    },
}
</script>

转自:https://juejin.cn/post/6844903910365200392#heading-2

上一篇:深入浅出wpf之Binding学习总结


下一篇:CDK Virtual scrolling 遇到的 bug