1.什么事自定义指令

指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for 例外)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

简单的讲就是: 指令是可以写在DOM元素的小命令,以v-为前缀,vue就能识别这是一个指令并保持语法的一致性。如果需要对HTML进行底层操作的话,这种方式是非常有用的。

1.2使用自定义指令的方式

//会实例化一个指令,但这个指令没有参数 
`v-xxx`
 
// -- 将值传到指令中
`v-xxx="value"`  
 
// -- 将字符串传入到指令中,如`v-html="'<p>内容</p>'"`
`v-xxx="'string'"` 
 
// -- 传参数(`arg`),如`v-bind:class="className"`
`v-xxx:arg="value"` 
 
// -- 使用修饰符(`modifier`)
`v-xxx:arg.modifier="value"` 

2.设置自定义组件

2.1 设置全局指令

Vue.directive('focus',{
        /*inserted函数表示当绑定了该指令的元素被插入到dom时候会自动触发*/
        inserted(el){
            console.log(el);
            /*获得焦点*/
            el.focus();
        }
    })

然后你可以在模板中任何元素上使用新的 v-focus property,如下:

<div id="app">
	//设置自定义指令v-xxx
    <input type="text" v-focus  placeholder="请输入用户名">
</div>

2.2 设置私有指令

    let vm = new Vue({
        el: "#app",
        data: {},
        methods: {},
        directives: {
            red: {
                inserted(el) {
                    el.style.color = "red"
                }
            },
            test: {
                bind(el) {
                    console.log('bind函数只会调用一次,指令第一次被绑定到元素被触发');
                },
                inserted(el, binding, vnode, oldVnode) {
                    /*
                    * el表示当顶了该指令的dom对象
                    * binding是一个包含了指令各种信息的对象:指令名,指令值,指令表达式和一个包含了修饰符的对象
                    * */
                    console.log( el);
                    console.log(binding);
                    console.log(vnode);
                    console.log('inserted函数在组件被渲染时候调用');
                },
                update() {
                    console.log('update函数在所有组件的VNode对象更新时调用');
                },
                componentUpdated() {
                    console.log('componentUpdated指令所在组件的VNode对象和其子类VNode对象全部更新后调用');
                },
                unbind() {
                    console.log('unbind指令解绑时候被调用');
                }
            },
            color: {
                inserted(el, bind) {
                    let color = bind.value || "red";
                    el.style.color = color;
                }
            }
        }
    });

在这里插入图片描述

<div id="app">
    <input type="text" v-focus  placeholder="请输入用户名">
    <p v-red>v-red</p>
    <p v-test="100" v-color="'orange'">测试指令</p>
</div>

在这里插入图片描述

2.3 钩子函数

自定义指令也像组件那样存在钩子函数:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子
    VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
  • unbind:只调用一次,指令与元素解绑时调用

所有的钩子函数的参数都有以下:

  • el:指令所绑定的元素,可以用来直接操作 DOM
  • binding:一个对象,包含以下 property:

`name`:指令名,不包括 v- 前缀。

`value`:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

`oldValue`:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

`expression`:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

`arg`:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。

`modifiers`:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }

`vnode`:Vue 编译生成的虚拟节点

`oldVnode`:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

3. 案例

<body>
<div id="app">
    <button type="button" v-sub="{fn:submit,time:2000}">提交</button>
</div>
</body>
<script>
    let vm = new Vue({
        el: "#app",
        data: {},
        methods: {
            submit(){
                console.log('数据提交');
            }
        },
        directives:{
            sub:{
                inserted(el,binding){
                   let fn = binding.value.fn;
                   let time = binding.value.time;
                   el.flag = true;/*设置按钮默认可以点击*/
                    /*handle:watch中需要具体执行的方法*/
                   el.handler = function (){
                        if (el.flag){
                            fn();
                            el.disabled = true;
                            el.flag = false;
                        }
                        el.time = setTimeout(()=>{
                            el.disabled = false;
                            el.flag = true;
                        },time);
                   }
                    console.log(el);
                    console.log(binding);
                    console.log(el.handler);
                    console.log("---------------")
                   console.log(fn);
                   console.log(time);
                    /*给DOM绑定单击事件*/
                   el.addEventListener('click',el.handler);
                }
            }
        }
    });
</script>

最后的console.log:
在这里插入图片描述

————————————————

部分的原文链接:https://blog.csdn.net/weixin_43638968/article/details/103603393

Logo

前往低代码交流专区

更多推荐