防抖函数基本原理:setTimeout和clearTimeout的运用
关键代码:
let timer:any=null;
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
// ...略
}, delay);
防抖函数钩子文件:
import { ref, watch, type Ref, type UnwrapRef, onUnmounted } from "vue";// 优化抖动问题
interface IDebounceFn<T> {(...args : T[]) : void | Promise<void>
}// 普通防抖函数(利用setTimeout, clearTimeout, 闭包)
export const debounceFn = <T>(fn: IDebounceFn<T>, delay: number) => {let timer:any = null;function f(this:void, ...args:T[]) {if(timer) {clearTimeout(timer)}timer = setTimeout(() => {fn.call(this, ...args);}, delay);}return f;
}// 钩子函数可以使用很多vue自带的比如watch, computed, ref, 生命周期钩子等(如果要用于react, 就使用react相关的钩子, 生命周期等, 基本逻辑差不多)
const useDebounce=<T>(value:Ref<T>, delay:number)=> {const debounceValue = ref(value.value)let timer:any=null;const unwatch = watch(value, (nv) => {if(timer) {clearTimeout(timer)}timer = setTimeout(() => {debounceValue.value = nv as UnwrapRef<T>}, delay);})onUnmounted(() => {// 避免一直watchunwatch()})return debounceValue;
}export default useDebounce;
使用普通防抖函数debounceFn的时候:
const searchValue = ref(''); // 存储输入框的值
const bounceWatch = (nv:string)=> {if(!nv) {// 搜索结果清空, 代码略}// 触发搜索函数, 代码略
}
watch(searchValue, debounceFn(bounceWatch, 1000)); // 监听输入框的值,防止调用太多查询接口,输入完成后才调用接口查询
使用useDebounce钩子函数时:
const searchValue = ref(''); // 存储输入框的值
const bounceWatch = (nv:string)=> {if(!nv) {// 搜索结果清空, 代码略}// 触发搜索函数, 代码略
}// 利用防抖函数获取搜索框的值,再监听该值,输入完成后再调用查询接口
const debounceValue = useDebounce(searchValue, 1000)
watch(debounceValue, bounceWatch)