手摸手写一个vue自定义节流指令

437 阅读2分钟

好了话不多说,直接切入正题。 不要聊了,不要聊了,先上code,先上code.

import Vue from 'vue';
const throttle = Vue.directive('throttle', {
  inserted: function (el, binding, vnode) {
    const { arg, value } = binding;
    let lastTime = null;
    let func = null; const that = vnode.context;
    el.addEventListener('click', event => {
      const nowTime = Date.now();
      if (lastTime && lastTime - nowTime < 800) {
        clearTimeout(func);
        func = setTimeout(() => {
          lastTime = nowTime;
          typeof arg === 'function' ? arg.call(that, value) : null;
        }, 800);
      } else {
        lastTime = nowTime;
        typeof arg === 'function' ? arg.call(that, value) : null;
      }
    }, true);
  }
});
export default throttle;

一步一步分析 首先引入VUE这是总所周知的,使用directive方法注册自定义指令;如果不太了解这里有传送门cn.vuejs.org/v2/guide/cu…; directive方法接收两个参数,第一个为指令即v-xxx(这xxx就是这里的指令),第二个参数是一个对象,该对象有几个钩子函数(都是可选)即:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。 每个钩子函数的参数 (el、binding、vnode 和 oldVnode)具体的的我就不在赘述了,详细了解可查看上边的传送门。 这里我用了inserted这个钩子函数,因为页面渲染完后,像搜索表单,table里边的slot这些一般都是可以找到父节点的。 通过el可以对被绑定的元素做监听,这边因为点击的时候防止连续多次触发相同的请求,就去监听该元素的动作,即点击操作,然后写下节流方法,如果在规定的时间节点内,重复点击只有一次生效。其他的我就不说了,就这里的代码;即判断当前参数是否为函数,如果是就执行arg.call(that, value)这个方法,这里的arg是你点击的操作事件,用call绑定vue实例,that为vnode该元素节点的content,这里的上下文即为VUE实例。最后是value是即点击事件的参数。 到这差不多结束了。这是自己的见解,望大佬看到有错的地方,请时指出,我便及时纠正免得误导他人。谢谢