useDebounce.js
import { ref, watchEffect } from "vue";
export function useDebounce(fn, delay = 300) {
const timeout = ref(null);
const debounced = (...args) => {
if (timeout.value) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(() => {
fn(...args);
}, delay);
};
const cancel = () => {
if (timeout.value) {
clearTimeout(timeout.value);
timeout.value = null;
}
};
watchEffect(() => {
if (timeout.value) {
return () => clearTimeout(timeout.value);
}
});
return { debounced, cancel };
}
export function useThrottle(func, delay = 300) {
let timeout;
let lastArgs;
let lastCall = new Date().getTime();
function throttled(...args) {
const now = new Date().getTime();
const timeSinceLastCall = now - lastCall;
console.log("timeSinceLastCall", timeSinceLastCall);
if (timeSinceLastCall >= delay) {
// console.log("timeSinceLastCall >= delay");
lastCall = now;
func(...args);
} else {
// console.log("timeSinceLastCall < delay");
lastArgs = args;
clearTimeout(timeout);
timeout = setTimeout(() => {
lastCall = now;
func(...lastArgs);
}, delay - timeSinceLastCall);
}
}
throttled.cancel = function () {
clearTimeout(timeout);
lastCall = new Date().getTime()
};
return { throttled, cancel: throttled.cancel };
}
举例使用:
import { ref } from 'vue';
import { useDebounce, useThrottle } from './useDebounce';
export default {
setup() {
const input = ref('');
const debouncedValue = ref('');
const throttledValue = ref('');
const { debounced: debouncedInput } = useDebounce((value) => {
debouncedValue.value = value;
});
const { throttled: throttledInput } = useThrottle((value) => {
throttledValue.value = value;
});
const onInput = (event) => {
const value = event.target.value;
debouncedInput(value);
throttledInput(value);
};
return { input, debouncedValue, throttledValue, onInput };
},
};