47 lines
1.1 KiB
TypeScript
47 lines
1.1 KiB
TypeScript
import { ref } from 'vue';
|
|
|
|
/**
|
|
* 节流函数封装
|
|
* @param fn 需要节流的函数
|
|
* @param delay 节流间隔时间(ms),默认 500
|
|
* @returns 返回节流后的函数,连续调用时只会在每个 delay 周期内执行一次
|
|
*/
|
|
export function useThrottleFn<T extends (...args: any[]) => any>(
|
|
fn: T,
|
|
delay: number = 500,
|
|
): T & { cancel: () => void } {
|
|
const lastTime = ref<number>(0);
|
|
let timer: any = null;
|
|
|
|
const throttled = function (this: any, ...args: any[]) {
|
|
const now = Date.now();
|
|
const remaining = delay - (now - lastTime.value);
|
|
|
|
if (remaining <= 0) {
|
|
// 冷却时间已过,立即执行
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
lastTime.value = now;
|
|
fn.apply(this, args);
|
|
} else if (!timer) {
|
|
// 冷却时间未过,延后执行
|
|
timer = setTimeout(() => {
|
|
lastTime.value = Date.now();
|
|
timer = null;
|
|
fn.apply(this, args);
|
|
}, remaining);
|
|
}
|
|
} as T & { cancel: () => void };
|
|
|
|
throttled.cancel = () => {
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
};
|
|
|
|
return throttled;
|
|
}
|