1.建一个 debounce.ts 文件
import { App, Component, DirectiveBinding, VNode } from 'vue';
import { ElMessage } from 'element-plus';
type voidFn = (...args: any[]) => void;
function debounce(fn: voidFn, delay?: number | string, immediate?: boolean): voidFn {
if (delay === undefined) {
delay = 500;
}
if (immediate === undefined) {
immediate = false;
}
let timer: NodeJS.Timeout | null;
return (...args: any[]) => {
if (timer) {
clearTimeout(timer);
ElMessage({
type: 'warning',
message: '请勿频繁操作',
duration: 2000
})
};
if (immediate) {
const callnow = !timer;
timer = setTimeout(() => {
timer = null;
}, Number(delay));
if (callnow) fn(...args);
} else {
timer = setTimeout(() => {
fn(...args);
}, Number(delay));
}
};
}
export default {
install(Vue: App, options: Component) {
Vue.directive('debounce', {
beforeMount(el: HTMLElement, { arg, value, modifiers }, vnode: VNode) {
let modifiersList = modifiers && Object.keys(modifiers);
let delay = (modifiersList.length && modifiersList[0]) || 500;
let immediate = modifiers.immediate || false;
let d_fn = debounce(value.bind(vnode), delay, immediate);
el.addEventListener(arg || 'click', (ev) => {
d_fn(ev);
});
},
});
},
};
2.在main.ts 引入
import debounce from './directive/debounce';
app.use(debounce )
3.使用
<!-- 不带参数 -->
<button v-debounce:click.3000.immediate="handleClick1">点击</button>
<!-- 带参数 -->
<button v-debounce:click.3000.immediate="handleClick1.bind(null, '1', '2')">点击</button>