vue2节流指令封装

directives
    |-----index.js
    |-----throttle.js

挂载

// main.js
import directives from "./directives";

Vue.use(directives);

代码实现

// index.js
import Vue from "vue";
import throttle from "./throttle";

const install = function (Vue) {
  Vue.directive("throttle", throttle);
};

if (window.Vue) {
  Vue.use(install);
}

export default install;

// throttle.js
/*
 * @Description: 节流指令
 * @Author: 蜗牛
 * @Date: 2022-11-17 17:37:50
 */

// # 使用方式
// 方式1: <button v-throttle:click="myfun"></button>
// 方式2: <button v-throttle:input="{fun:myfun, args:[a, b, c]}"></button>
// 方式3: <button v-throttle:click.stop="{fun:myfun, args:[a, b, c], delay: 1000}"></button>

// # API文档
// 参数     类型      必须    默认值      可选项
// event    string    true    ""            /
// modifier string    false   undefined   stop(取消冒泡)/prev(阻止默认行为)
// fun      function  true    null          /
// args     array     false   undefined     /
// delay    number    false   300           /

let fn = null;
let myEvent = "";
let myModifier = "";

export default {
  inserted: function (el, binding) {
    let myFunc = null;
    let myArgs = null;
    let delay = 300;
    let timer = null;
    myEvent = binding.arg;
    if (!myEvent) {
      console.error("v-throttle must specify an event type");
      return;
    }
    myModifier = binding.modifiers;
    const bindVal = binding.value;
    if (typeof bindVal === "function") {
      myFunc = bindVal;
    } else {
      myFunc = bindVal.fun;
      myArgs = bindVal.args ? bindVal.args : myArgs;
      delay = bindVal.delay ? bindVal.delay : delay;
      console.log(myFunc, myArgs, delay);
    }
    fn = (e) => {
      if (myModifier.prev) {
        e.preventDefault();
      }
      if (myModifier.stop) {
        e.stopPropagation();
      }
      if (timer) {
        return;
      }
      timer = setTimeout(() => {
        if (myFunc && myArgs) {
          myFunc(...myArgs);
        } else if (myFunc && !myArgs) {
          myFunc();
        }
        timer = null;
      }, delay);
    };
    el.addEventListener(myEvent, fn);
  },
  unbind: function (el) {
    fn && el.removeEventListener(myEvent, fn);
  },
};

加强版

回调立即执行
变量挂载到el节点,修复多节点使用可能冲突问题

/*
 * @Description: 节流指令
 * @Author: 蜗牛
 * @Date: 2024-8-21 15:37:50
 */

// # 使用方式
// 方式1: <button v-throttle:click="myfun"></button>
// 方式2: <div v-throttle:scroll="{fun:myfun, args:[a, b, c]}"></div>
// 方式3: <button v-throttle:click.stop="{fun:myfun, args:[a, b, c], delay: 1000}"></button>

// # API文档
// 参数     类型      必须    默认值      可选项
// event    string    true    ""            /
// modifier string    false   undefined   stop(取消冒泡)/prev(阻止默认行为)
// fun      function  true    null          /
// args     array     false   undefined     /
// delay    number    false   300           /

export default {
  inserted: function (el, binding) {
    let myFunc = null;
    let myArgs = null;
    let delay = 300;
    let timer = null;
    el.__throttleEvent__ = binding.arg;
    if (!el.__throttleEvent__) {
      console.error("v-throttle must specify an event type");
      return;
    }
    el.__throttleModifier__ = binding.modifiers;
    const bindVal = binding.value;
    if (typeof bindVal === "function") {
      myFunc = bindVal;
    } else {
      myFunc = bindVal.fun;
      myArgs = bindVal.args ? bindVal.args : myArgs;
      delay = bindVal.delay ? bindVal.delay : delay;
      console.log(myFunc, myArgs, delay);
    }
    el.__throttleFn__ = (e) => {
      if (el.__throttleModifier__.prev) {
        e.preventDefault();
      }
      if (el.__throttleModifier__.stop) {
        e.stopPropagation();
      }
      if (timer) {
        return;
      }
      if (!el.disabled) {
        el.disabled = true;
        if (myFunc && myArgs) {
          myFunc(...myArgs);
        } else if (myFunc && !myArgs) {
          myFunc();
        }
        timer = setTimeout(() => {
          el.disabled = false;
          timer = null;
        }, delay);
      }
    };
    el.addEventListener(el.__throttleEvent__, el.__throttleFn__);
  },
  unbind: function (el) {
    el.__throttleFn__ &&
      el.removeEventListener(el.__throttleEvent__, el.__throttleFn__);
  }
};

posted @ 2024-08-21 15:16  Better-HTQ  阅读(50)  评论(0编辑  收藏  举报