Vue3+TS 封装所有事件通用的节流自定义指令
// src/utils/throttle.ts
export function throttle(fn: (...args: any[]) => void, delay: number) {
let lastCall = 0
return (...args: any[]) => {
const now = new Date().getTime()
if (now - lastCall >= delay) {
lastCall = now
fn(...args)
}
}
}
// directives/vThrottle.ts
import { Directive, DirectiveBinding } from "vue";
import { throttle } from "@/services/utils/throttle";
declare global {
interface HTMLElement {
__throttleHandlers__?: Array<{ event: string; handler: (event: Event) => void }>;
}
}
const vThrottle: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
if (typeof binding.value !== "function") {
console.warn(`v-throttle不是一个函数`);
return;
}
const delay = binding.arg ? parseInt(binding.arg, 10) : 300;
let eventTypes;
if (Object.keys(binding.modifiers).length === 0) {
eventTypes = ["click"];
} else {
eventTypes = Object.keys(binding.modifiers);
}
const throttledFunction = throttle(binding.value, delay);
el.__throttleHandlers__ = eventTypes.map((eventType) => ({
event: eventType,
handler: throttledFunction,
}));
el.__throttleHandlers__.forEach(({ event, handler }) => {
el.addEventListener(event, handler);
});
},
beforeUnmount(el: HTMLElement) {
if (el.__throttleHandlers__) {
el.__throttleHandlers__.forEach(({ event, handler }) => {
el.removeEventListener(event, handler);
});
delete el.__throttleHandlers__;
}
},
};
export default vThrottle;
// main.ts
import vThrottle from '@/directives/vThrottle'
app.directive('throttle', vThrottle)
// 使用
v-throttle:时间.事件="函数"
默认事件click
v-throttle:5000="
() => {
console.log(666);
}"
v-throttle:500.scroll="
() => {
console.log(777);
}"
v-throttle:200.mousemove="
() => {
console.log(666);
}"
事件节流自定义指令v-throttle:时间.事件="函数 || 函数名"v-throttle:时间.事件="() => 函数名(形参)"
默认事件:click
节流函数使用
1.import { throttle } from “@/services/utils/throttle”;
2.const 函数名 = throttle(()=>{函数逻辑},500)