背景
我们需要做防抖的场景:下载按钮、购物车下单按钮等等,使用的场景比较多,可以公共化处理,全局防抖指令是其中的一种公共化处理方式。
代码实现
// 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>