vue3+vite中-自定义防抖指令

787 阅读1分钟

背景

我们需要做防抖的场景:下载按钮、购物车下单按钮等等,使用的场景比较多,可以公共化处理,全局防抖指令是其中的一种公共化处理方式。

代码实现

// debounce.js v-debounce 使用lodash的防抖函数
import { debounce } from 'lodash';
export default {
  mounted(el, binding) {
    if (typeof binding.value !== 'function') {
      console.error('callback must be a function');
      return;
    }
    el.__handleClick__ = debounce(binding.value, 200);
    el.addEventListener('click', el.__handleClick__);
  },
  beforeUnmount(el) {
    el.removeEventListener('click', el.__handleClick__);
  }
};
// debounce.js v-debounce 自己写防抖函数
function debounce(fn, wait) {
  let timer = null;
  return function (...args) {
    let context = this;
    if (timer) {
      clearInterval(timer);
      timer = null;
    }
    timer = setTimeout(() => {
      return fn.apply(context, args);
    }, wait);
  };
}
export default {
  mounted(el, binding) {
    if (typeof binding.value !== 'function') {
      console.error('callback must be a function');
      return;
    }
    el.__handleClick__ = debounce(binding.value, 200);
    el.addEventListener('click', el.__handleClick__);
  },
  beforeUnmount(el) {
    el.removeEventListener('click', el.__handleClick__);
  }
};

注册

  // 单个注入
import debounce from './debounce'
const app = createApp(App);
app.directive('debounce', debounce);

指令多起来的话,还一个个注册的话,会很麻烦,每新增一个自定义指令都要手动引入,有重复性的工作,在vite可以使用import.meta.globEager替换require.context,实现自动读取目录文件,引入模块,并自动注册:

const directives = import.meta.globEager('.//*.js');
export default function (app) {
    for (let com in directives) {
      const comKey = com.match(/\.\/(.*?)\.js/)[1];
      const comValue = directives[com].default;
      app.directive(comKey, comValue);
    }
}

使用

<template> <button v-debounce="sayHello"> 确定</button></template>
<script setup lang="ts">
    const sayHello = () => {
      console.log('hello world');
    };
</script>