39 lines
1.0 KiB
TypeScript
39 lines
1.0 KiB
TypeScript
import { ref } from 'vue';
|
||
|
||
/**
|
||
* 按钮节流Hook
|
||
* @param callback 点击后执行的业务逻辑回调
|
||
* @param delay 节流时间(默认1500ms)
|
||
* @returns 节流后的点击事件函数
|
||
* @template T 回调函数的参数类型(支持多参数元组)
|
||
*/
|
||
export const useThrottle = <T extends any[]>(
|
||
callback: (...args: T) => void | Promise<void>,
|
||
delay: number = 1500
|
||
) => {
|
||
// 标记是否可点击
|
||
const isClickable = ref(true);
|
||
|
||
// 节流后的函数,支持传递任意参数
|
||
const throttledFn = async (...args: T) => {
|
||
if (!isClickable.value) return;
|
||
|
||
// 锁定按钮
|
||
isClickable.value = false;
|
||
|
||
try {
|
||
// 执行业务回调,支持异步函数
|
||
await callback(...args);
|
||
} catch (error) {
|
||
console.error('节流回调执行失败:', error);
|
||
throw error; // 抛出错误,方便组件内捕获
|
||
} finally {
|
||
// 延迟后解锁按钮(无论成功/失败都解锁)
|
||
setTimeout(() => {
|
||
isClickable.value = true;
|
||
}, delay);
|
||
}
|
||
};
|
||
|
||
return throttledFn;
|
||
}; |