feat: Architecture initialization
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
// src/hooks/useDebounce.ts
|
||||
import { watch, onUnmounted } from 'vue';
|
||||
import { useState } from './useState';
|
||||
|
||||
export interface UseDebounceOptions {
|
||||
delay?: number;
|
||||
immediate?: boolean;
|
||||
maxWait?: number;
|
||||
}
|
||||
|
||||
export function useDebounce<T>(
|
||||
source: any, // Ref<T>
|
||||
options: number | UseDebounceOptions = {},
|
||||
) {
|
||||
const config = typeof options === 'number' ? { delay: options } : options;
|
||||
const { delay = 300, immediate = false, maxWait } = config;
|
||||
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(source.value);
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
|
||||
let timer: any = null;
|
||||
let maxWaitTimer: any = null;
|
||||
let isFirstCall = true; // 标记是否为首次调用,用于 immediate 模式
|
||||
|
||||
// 清理
|
||||
const clearTimers = () => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
if (maxWaitTimer) {
|
||||
clearTimeout(maxWaitTimer);
|
||||
maxWaitTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
// 更新
|
||||
const updateValue = () => {
|
||||
setDebouncedValue(source.value);
|
||||
setIsPending(false);
|
||||
clearTimers();
|
||||
// 安静期结束后重置 isFirstCall,使下次触发能立即执行(immediate 模式)
|
||||
isFirstCall = true;
|
||||
};
|
||||
|
||||
watch(source, () => {
|
||||
setIsPending(true);
|
||||
|
||||
// 处理 maxWait
|
||||
if (maxWait && !maxWaitTimer) {
|
||||
maxWaitTimer = setTimeout(() => {
|
||||
updateValue();
|
||||
}, maxWait);
|
||||
}
|
||||
|
||||
// 处理 delay
|
||||
if (timer) clearTimeout(timer);
|
||||
|
||||
if (immediate && isFirstCall) {
|
||||
isFirstCall = false;
|
||||
updateValue();
|
||||
} else {
|
||||
timer = setTimeout(() => {
|
||||
updateValue();
|
||||
}, delay);
|
||||
}
|
||||
});
|
||||
|
||||
// 卸载
|
||||
onUnmounted(() => {
|
||||
clearTimers();
|
||||
});
|
||||
|
||||
return {
|
||||
debouncedValue,
|
||||
isPending,
|
||||
refresh: updateValue,
|
||||
cancel: clearTimers,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user