8个非常实用的Vue自定义指令

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8个非常实用的Vue自定义指令相关的知识,希望对你有一定的参考价值。

参考技术A 在 Vue,除了核心功能默认内置的指令 ( v-model 和 v-show ),Vue 也允许注册自定义指令。它的作用价值在于当开发人员在某些场景下需要对普通 DOM 元素进行操作。

Vue自定义指令有全局注册和局部注册两种方式。先来看看注册全局指令的方式,通过 Vue.directive( id, [definition] ) 方式注册全局指令。然后在入口文件中进行 Vue.use() 调用。

批量注册指令,新建 directives/index.js 文件

在 main.js 引入并调用

指令定义函数提供了几个钩子函数(可选):

下面分享几个实用的 Vue 自定义指令

需求:实现一键复制文本内容,用于鼠标右键粘贴。

思路:

使用:给 Dom 加上 v-copy 及复制的文本即可

需求:实现长按,用户需要按下并按住按钮几秒钟,触发相应的事件

思路:

使用:给 Dom 加上 v-longpress 及回调函数即可

背景:在开发中,有些提交保存按钮有时候会在短时间内被点击多次,这样就会多次重复请求后端接口,造成数据的混乱,比如新增表单的提交按钮,多次点击就会新增多条重复的数据。

需求:防止按钮在短时间内被多次点击,使用防抖函数限制规定时间内只能点击一次。

思路:

使用:给 Dom 加上 v-debounce 及回调函数即可

背景:开发中遇到的表单输入,往往会有对输入内容的限制,比如不能输入表情和特殊字符,只能输入数字或字母等。

我们常规方法是在每一个表单的 on-change 事件上做处理。

这样代码量比较大而且不好维护,所以我们需要自定义一个指令来解决这问题。

需求:根据正则表达式,设计自定义处理表单输入规则的指令,下面以禁止输入表情和特殊字符为例。

使用:将需要校验的输入框加上 v-emoji 即可

背景:在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列表头图等。图片众多以及图片体积过大往往会影响页面加载速度,造成不良的用户体验,所以进行图片懒加载优化势在必行。

需求:实现一个图片懒加载指令,只加载浏览器可见区域的图片。

思路:

图片懒加载有两种方式可以实现,一是绑定 srcoll 事件进行监听,二是使用 IntersectionObserver 判断图片是否到了可视区域,但是有浏览器兼容性问题。

下面封装一个懒加载指令兼容两种方法,判断浏览器是否支持 IntersectionObserver API,如果支持就使用 IntersectionObserver 实现懒加载,否则则使用 srcoll 事件监听 + 节流的方法实现。

使用,将组件内 标签的 src 换成 v-LazyLoad

背景:在一些后台管理系统,我们可能需要根据用户角色进行一些操作权限的判断,很多时候我们都是粗暴地给一个元素添加 v-if / v-show 来进行显示隐藏,但如果判断条件繁琐且多个地方需要判断,这种方式的代码不仅不优雅而且冗余。针对这种情况,我们可以通过全局自定义指令来处理。

需求:自定义一个权限指令,对需要权限判断的 Dom 进行显示隐藏。

思路:

使用:给 v-permission 赋值判断即可

需求:给整个页面添加背景水印

思路:

使用,设置水印文案,颜色,字体大小即可

需求:实现一个拖拽指令,可在页面可视区域任意拖拽元素。

思路:

使用: 在 Dom 上加上 v-draggable 即可

Vue_(组件)自定义指令

 

 

  Vue.js自定义指令  传送门

 

技术图片

 

  自定义指令:除了内置指令,Vue也允许用户自定义指令

  注册指令:通过全局API Vue.directive可以注册自定义指令

 

  自定义指令的钩子函数参数:自定义指令的钩子函数可以传递4个参数,分别是el、binding、vnode、oldVnode

 

  Learn

    一、自定义指令钩子函数

    二、自定义指令钩子函数的参数

    三、自定义指令简写

 

  项目结构

  技术图片

  【每个demo下方都存有html源码】

 

 

一、自定义指令钩子函数  传送门

  自定义指令的钩子函数:

    bind:只调用一次,指令第一次绑定到元素时调用

    inserted:被绑定元素插入父节点时调用

    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前

    componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用

    unbind:只调用一次,指令与元素解绑时调用

  自定义指令的使用:在自定指令的名称前加 上 v-;

 

  通过button点击按钮来控制是否解除绑定

<div id="GaryId">
    <input type="text" v-model="name"/><br />
    name:<span v-if="flag"  v-demo ref=‘name‘>{{name}}</span><br />
    <button @click="flag=!flag">解除绑定</button>
</div>  

 

Vue.directive(‘demo‘,{
        //指令的钩子函数
        bind(){
            alert("bind 首次绑定到元素时候执行,执行一次,常用于数据的初始化操作");
        },
        inserted(){
            alert("instered 插入到父节点之后,DOM对象");
        },
        unbind(){
            alert("unbind 解除绑定");
        },
        update(){
            alert("updata 绑定该指令的元素 所在的Vue实例挂载的DOM树 发生更新时候调用"+"name ="+vm.$refs.name.textContent);
        },
        componentUpdated(){
            alert("componentUpdated 更新后调用"+"name ="+vm.$refs.name.textContent);
        }
    
    });

 

技术图片

 

技术图片
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Gary</title>
    <script type="text/javascript"  src="../js/vue.js"></script>
    
</head>
<body>
<div id="GaryId">
    <input type="text" v-model="name"/><br />
    name:<span v-if="flag"  v-demo ref=‘name‘>{{name}}</span><br />
    <button @click="flag=!flag">解除绑定</button>
</div>  
</body>

<script>

    Vue.directive(demo,{
        //指令的钩子函数
        bind(){
            alert("bind 首次绑定到元素时候执行,执行一次,常用于数据的初始化操作");
        },
        inserted(){
            alert("instered 插入到父节点之后,DOM对象");
        },
        unbind(){
            alert("unbind 解除绑定");
        },
        update(){
            alert("updata 绑定该指令的元素 所在的Vue实例挂载的DOM树 发生更新时候调用"+"name ="+vm.$refs.name.textContent);
        },
        componentUpdated(){
            alert("componentUpdated 更新后调用"+"name ="+vm.$refs.name.textContent);
        }
    
    });
    
    let vm = new Vue({
        data:{
            name:Gary,
            flag:true
        }
    }).$mount(#GaryId);

</script>


 </html>
Gary_Custom_Directive.html

 

 

二、自定义指令钩子函数的参数  传送门

  自定义指令的钩子函数参数:自定义指令的钩子函数可以传递4个参数,分别是el、binding、vnode、oldVnode;

  el:获取DOM对象;

  binding:一个包含很多属性的对象;

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

  oldVnode:上一个虚拟节点;

技术图片

 

技术图片
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Gary</title>
    <script type="text/javascript"  src="../js/vue.js"></script>
    
</head>
<body>
<div id="GaryId">
            <input type="text" v-model="name" /><br />
            name : <span v-demo.once.stop=‘name‘ ref=‘name‘>{{name}}</span><br />
            <button v-on:click="flag = !flag">click
</body>

<script>

    Vue.directive(demo,{
        //指令的钩子函数
        bind(el,binding){
            //console.log(el);
            el.style.color=red;
            console.log(binding.name);
            console.log(binding.value);
            
            console.log(binding.expression);
            console.log(binding.arg);
            console.log(binding.modifiers);
            
                if(binding.arg === click){
                    console.log("执行点击事件");
                }
                
                if(binding.modifiers.once){
                    console.log("只执行一次");
                }
            
        },
        update(el,binding){
            console.log("update value = "+binding.value);
            console.log("update oldValue = "+binding.oldValue);
        }
    });
    
    let vm = new Vue({
        data:{
            name:Gary,
            flag:true
        }
    }).$mount(#GaryId);

</script>


 </html>
Gary_Custom_Directive-02.html

 

 

三、自定义指令简写  传送门

  通过directives指令和focus指令实现修改样式和加载页面时自动聚焦

<div id="GaryId">
            <!--通过v-focus标签,当页面加载时,自动聚焦到这个表单上-->
            <input type="text" v-model="name"  v-focus/><br />
            name : <span v-font_style:blue>{{name}}</span><br />
</body>

 

      directives : {
            font_style : function(el, binding){
                el.style.color = binding.arg;
            },
            //聚焦
            focus:{
                inserted(el){
                    el.focus();
                }
            }    

 

技术图片

 

技术图片
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Gary</title>
    <script type="text/javascript"  src="../js/vue.js"></script>
    
</head>
<body>
<div id="GaryId">
            <!--通过v-focus标签,当页面加载时,自动聚焦到这个表单上-->
            <input type="text" v-model="name"  v-focus/><br />
            name : <span v-font_style:blue>{{name}}</span><br />
</body>

<script>


        let vm = new Vue({
            data : {
                name : Gary,
                flag : true
            },
            directives : {
                font_style : function(el, binding){
                    el.style.color = binding.arg;
                },
                focus : {
                    inserted(el){
                        el.focus();
                    }
                }
            }
    }).$mount(#GaryId);

</script>


 </html>
Gary_Custom_Directive-03.html

 

以上是关于8个非常实用的Vue自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

分享8个非常实用的Vue自定义指令

超实用:Vue 自定义指令合集

Vue3自定义指令v-copy实现复制文字

Vue3自定义指令v-copy实现复制文字

Vue3自定义指令v-copy实现复制文字

Vue:八种实用的自定义指令