【vue中如何自定义指令directive + 使用的场景(防抖动、图片懒加载、一键 Copy的功能、拖拽)】

一、什么是自定义指令?

只要看到 v- 开头的,都是指令,不同的指令都有实现不同的功能,可以对普通DOM元素进行底层,这时候就该用到自定义指令,除了核心的内置指令外(比如:v-show、v-model),Vue也可以注册自定义指令

自定义指令又分为:全局自定义指令、局部自定义指令、

二、使用自定义指令又分为了一下几种方式?

//会实例化一个指令,但这个指令没有参数 
`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"` 

三、如何注册自定义指令?

注册一个自定义指令有:全局自定义指令、局部自定义指令、

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

  • 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 钩子中可用

  • VNode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

全局自定义指令是在main.js中,通过 Vue.directive进行注册
使用方法:

 <div v-focus>自定义指令</div>    //页面中的使用

// 注册一个全局自定义指令 `v-focus`
Vue.directive("focus", {    //常用的一定要会,面试的时候面试官也是经常用的,不经常用的但是也要知道

  bind(el, binding) {
    //比较常用的
    console.log("元素第一次绑定上时进行调用");
  },

  inserted(el, binding, VNode) {
    //比较常用的
    console.log("元素插入父节点时进行调用");
  },

  update(el, binding) {
    //一般不经常使用
    console.log("组件的 VNode 更新时进行调用");
  },

  componentUpdated(el, binding) {
    //一般不经常使用
    console.log("组件的 VNode 及子 VNode 全部更新后调用");
  },
  
  unbind(el, binding) {
    //一般不经常使用
    console.log("元素解绑时进行调用");
  },
});

局部注册是在当前组件中,通过 directives 进行注册
使用方法:

 <div v-focus>自定义指令</div>    //页面中的使用

 directives: {
    focus: {
      bind(el, binding) {
        //比较常用的
        console.log("元素第一次绑定上时进行调用");
      },

      inserted(el, binding, VNode) {
        //比较常用的
        console.log("元素插入父节点时进行调用");
      },

      update(el, binding) {
        //一般不经常使用
        console.log("组件的 VNode 更新时进行调用");
      },

      componentUpdated(el, binding) {
        //一般不经常使用
        console.log("组件的 VNode 及子 VNode 全部更新后调用");
      },

      unbind(el, binding) {
        //一般不经常使用
        console.log("元素解绑时进行调用");
      },
    },
  },

四、应用场景

使用自定义组件组件可以满足我们日常一些场景,这里给出几个自定义组件的案例:

  • 防抖动
  • 图片懒加载
  • 一键 Copy的功能
  • 拖拽

拖拽

 <div id="ab" v-drag></div>    //要拖拽的那个div
 
   //样式
 #ab{
  width: 100px;
  height: 100px;
  background-color: red;
  position: absolute;   //完成拖拽的话,需要给样式里边添加一个 position: absolute; 才行
}

//局部自定义指令
 directives: {
    drag: {
      bind() {},
      inserted(el) {
        el.onmousedown = (e) => {
          let x = e.clientX - el.offsetLeft;
          let y = e.clientY - el.offsetTop;
          document.onmousemove = (e) => {
            let xx = e.clientX - x + "px";
            let yy = e.clientY - y + "px";
            el.style.left = xx;
            el.style.top = yy;
          };
          el.onmouseup = (e) => {
            document.onmousemove = null;
          };
        };
      },
    },
  },
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值