Vue自定义指令——函数式与对象式以及注意事项

作者:CSDN-PleaSure乐事

欢迎大家阅读我的博客 希望大家喜欢

使用环境:vscode Chrome浏览器

目录

1.什么是自定义指令

1.1定义

2.函数式自定义指令

2.1定义

2.2书写格式与效果

3.对象式自定义指令

3.1定义

3.2书写格式与效果

4.需要注意的坑

4.1命名

4.1.1问题

4.1.2原因

4.1.3解决方案

4.2指令回掉函数中的this问题

4.2.1问题演示

4.2.2原因

4.2.3解决方案


1.什么是自定义指令

1.1定义

自定义指令是Vue框架中的一个特性,允许开发者定义自己的指令来扩展Vue的内置指令(如 v-model, v-if, v-for 等)的功能。自定义指令可以让你封装可重用的行为,并在不同的地方重复使用这些行为,而不需要在每个组件中都编写相同的逻辑。

在Vue中,指令是以v-开头的特殊属性,它们会在DOM更新时触发一些效果。自定义指令可以让你定义这些特殊的行为。

2.函数式自定义指令

2.1定义

函数式自定义指令是Vue.js中自定义指令的一种简化形式,它允许你以更简洁的方式定义指令的行为。函数式指令通常用于简单的操作,不需要完整的钩子函数集合。这种类型的指令只需要一个函数即可定义,这个函数将在指令绑定到元素时被调用。

2.2书写格式与效果

我们需要将对象置于directives中,以此来实现函数式自定义指令。案例如下:

<body>
    <div id="root">
        <h2>当前的n大小为:{{n}}</h2>
        <h2>放大10倍后的n是:<span v-big="n"></span></h2>
        <button @click="n++">点我++</button>
    </div>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            },
            //v-big的函数式自定义指令,通过binding对对象进行绑定,最终实现同步增大效果
            directives:{
                big(element,binding){
                    //使用binding.value来获取绑定的值
                    element.innerText = binding.value * 10;
                }
            }
        })
    </script>
</body>

初始值为1,而在点击自增按钮后会同步增加。

3.对象式自定义指令

3.1定义

对象式自定义指令是Vue中自定义指令的一种形式,它允许定义一组生命周期钩子函数来控制指令的行为。与函数式自定义指令不同,对象式自定义指令提供了更多的灵活性,因为它允许定义多个钩子函数来处理指令的不同生命周期阶段。

3.2书写格式与效果

对象式指令所放的位置仍旧在dirictive当中,但是格式有所不同:

directives:{
    big(element,binding){
        //使用binding.value来获取绑定的值
        element.innerText = binding.value * 10;
    },
    fbind:{
        bind(){},
        inserted(){},
        update(){},
    }
}

 其中在大括号当中我们填入相应的执行代码。

<body>
    <div id="root">
        <h2>当前的n大小为:{{n}}</h2>
        <h2>放大10倍后的n是:<span v-big="n"></span></h2>
        <button @click="n++">点我++</button><br>
        <input type="text" v-fbind:value="n">
    </div>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            },
            directives:{
                big(element,binding){
                    element.innerText = binding.value * 10
                },
                fbind:{
                    //指令与元素成功绑定
                    bind(element,binding){
                        element.value = binding.value
                    },
                    //指令所在元素倍插入页面
                    inserted(element,binding){
                        element.focus()
                    },
                    //指令所在模版被重新解析
                    update(element,binding){
                        element.value = binding.value
                    }
                }
            }
        })
    </script>
</body>

当我们需要在不同阶段使用自定义指令时,我们就可以使用对象式自定义指令。

4.需要注意的坑

4.1命名

4.1.1问题

如果我们采用驼峰式命名,则会产生报错:

<h2>放大10倍后的n是:<span v-bigNumber="n"></span></h2>

4.1.2原因

产生这个问题的原因如下,主要有两点:

  1. 在HTML中,属性名(包括自定义指令的名称)是不区分大小写的。因此,浏览器会将所有的属性名转换为小写形式。
  2. Vue在处理自定义指令时,会将驼峰式命名转换为短横线分隔的形式。

4.1.3解决方案

因为出现v-big,因此当我们使用多个单词进行拼接命名式,我们最好也使用v-big-number的形式进行命名,并最终在调用函数时使用引号包裹:

<h2>放大10倍后的n是:<span v-big-umber="n"></span></h2>

'big-number'(element,binding){
    element.innerText = binding.value * 10
}

同时我们推荐使用更加完整的写法:'big-number':function的形式,我们上面用到的都是简写形式,两者效果一致,无伤大雅。

4.2指令回掉函数中的this问题

4.2.1问题演示

如果我们对自定义函数中的指令进行this的输出:

directives:{
    'big-number'(element,binding){
        console.log('big',this)
        element.innerText = binding.value * 10
    },
    fbind:{
        //指令与元素成功绑定
        bind(element,binding){
            console.log('fbind-bind',this)
            element.value = binding.value
        },
        //指令所在元素倍插入页面
        inserted(element,binding){
            console.log('fbind-inserted',this)
            element.focus()
        },
        //指令所在模版被重新解析
        update(element,binding){
            console.log('fbind-update',this)
            element.value = binding.value
        }
    }
}

我们会发现this指向的都是window属性。

4.2.2原因

所有指令相关的回掉函数中的this不是vm,this关键字在自定义指令的上下文中指向的是全局对象window。自定义指令的钩子函数内部的this默认指向全局对象。

4.2.3解决方案

为了在自定义指令中访问Vue实例,可以通过使用箭头函数来实现,因为箭头函数不会创建自己的this绑定,而是从外层作用域继承this的值。如:

'big-number': (element, binding) => {
    console.log('big', this);
    element.innerText = binding.value * 10;
},

作者:CSDN-PleaSure乐事

希望我的博客对您有帮助,也希望在对您有帮助时您可以为我留下点赞收藏与关注,这对我真的很重要,谢谢!

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值