Vue如何自定义指令

最近在面试的时候多次被问到了Vue如何实现自定义指令的问题,之前没有了解过,也没有相应的使用经验。

Vue中为我们提供了非常多的指令,比如V-if, v-show, V-if, v-for等,非常非常多,并且Vue也支持我们自定义指令,来满足自己的业务的需求,达到复用的效果。可以全局注册,也可以局部注册。

全局自定义指令

有一次面试中,面试官的需求就是,设计一个全局自定义指令v-input, 如果input输入的字符中包括HelloWorld, 就提示成功, 并且禁止继续输入。如果input输入的字符长度大于15, 提示失败, 并且也禁止继续输入。

想达到全局的效果,其实我们可以写在main.js中。

main.js
import Vue from 'vue';

Vue.directive('input', {
    
    
  inserted: function(el, binding) {
    
    
    el.addEventListener('input', function() {
    
    
      if (el.value.indexOf('HelloWorld') !== -1) {
    
    
        alert('成功');
        el.disabled = true;
      }else if(el.value.length > 15) {
    
    
        alert('失败');
        el.disabled = true;
      }
    })
  }
})

首先先看一下这个directive方法的用法, 第一个参数是你v-后面的那个字符, 比如我想写一个v-input指令, 这里就写input, 第二个参数是一个对象, 对象中最重要的就是这个inserted属性, 这个属性接收一个函数。

函数里有两个很重要的参数, 第一个参数是你绑定这个指令的组件DOM节点, 虽然Vue倡导的是数据驱动视图, 不要轻易去动DOM, 但是某种需求下, 还是必须要到DOM的。第二个参数是一个对象, 如果你在用这个指令的时候赋了值, 在这个对象里可以取到。比如我在用的时候v-input="CreatorRay", 我在第二个参数里就可以取到这个CreatorRay

<template>
  <div>
    <input type="text" v-input="name" />
  </div>
</template>

<script>
  export default {
      
      
    data() {
      
      
      return {
      
      
        name: 'CreatorRay'
      };
    },
  }
</script>

image.png

搞清楚这个directive怎么用了之后, 就可以来写需求了, 既然我们可以拿到DOM节点, 需求就好实现了。先通过addEventListener监听input事件。

如果DOM节点.value通过indexOf方法查询HelloWorld字符串, 查不到返回-1, 查到后就直接alert成功, 并且把DOM节点.disabled = true, 就可以禁用input

如果DOM节点.value的长度大于15, alert失败, 也把DOM节点.value = true

知道怎么写自定义指令后, 实现需求还是比较简单的。

扫描二维码关注公众号,回复: 13389602 查看本文章

局部自定义指令

如果我们只想在某个组件内使用这个指令的话, 可以直接像data, methods, watch一样, 直接写一个directives属性, 内容基本一致。

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      name: "CreatorRay",
    };
  },
  directives: {
    
    
    input: {
    
    
      inserted: function (el, binding) {
    
    
        el.addEventListener("input", function () {
    
    
          if (el.value.indexOf("HelloWorld") !== -1) {
    
    
            alert("成功");
            el.disabled = true;
          } else if (el.value.length > 15) {
    
    
            alert("失败");
            el.disabled = true;
          }
        });
      },
    },
  },
};
</script>

猜你喜欢

转载自blog.csdn.net/m0_46171043/article/details/121170623