87 lines
2.2 KiB
JavaScript
87 lines
2.2 KiB
JavaScript
import { ref, onUnmounted } from 'vue';
|
|
|
|
/**
|
|
* Creates a debounced version of a function
|
|
* @param {Function} fn - The function to debounce
|
|
* @param {number} delay - The delay in milliseconds
|
|
* @returns {Function} - The debounced function
|
|
*/
|
|
export const useDebounceFn = (fn, delay = 300) => {
|
|
if (typeof fn !== 'function') {
|
|
throw new Error('First argument must be a function');
|
|
}
|
|
|
|
// Store the timeout ID for cleanup
|
|
const timeoutId = ref(null);
|
|
|
|
// Clean up any pending timeouts when the component is unmounted
|
|
onUnmounted(() => {
|
|
if (timeoutId.value) {
|
|
clearTimeout(timeoutId.value);
|
|
}
|
|
});
|
|
|
|
// Return the debounced function
|
|
return (...args) => {
|
|
// Clear previous timeout if exists
|
|
if (timeoutId.value) {
|
|
clearTimeout(timeoutId.value);
|
|
}
|
|
|
|
// Set a new timeout
|
|
timeoutId.value = setTimeout(() => {
|
|
fn(...args);
|
|
timeoutId.value = null;
|
|
}, delay);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Creates a throttled version of a function
|
|
* @param {Function} fn - The function to throttle
|
|
* @param {number} delay - The delay in milliseconds
|
|
* @returns {Function} - The throttled function
|
|
*/
|
|
export const useThrottleFn = (fn, delay = 300) => {
|
|
if (typeof fn !== 'function') {
|
|
throw new Error('First argument must be a function');
|
|
}
|
|
|
|
// Store the last execution time
|
|
const lastExecution = ref(0);
|
|
// Store the timeout ID for cleanup
|
|
const timeoutId = ref(null);
|
|
|
|
// Clean up any pending timeouts when the component is unmounted
|
|
onUnmounted(() => {
|
|
if (timeoutId.value) {
|
|
clearTimeout(timeoutId.value);
|
|
}
|
|
});
|
|
|
|
// Return the throttled function
|
|
return (...args) => {
|
|
const now = Date.now();
|
|
const elapsed = now - lastExecution.value;
|
|
|
|
// Clear any existing timeout
|
|
if (timeoutId.value) {
|
|
clearTimeout(timeoutId.value);
|
|
}
|
|
|
|
// If enough time has passed, execute immediately
|
|
if (elapsed >= delay) {
|
|
lastExecution.value = now;
|
|
fn(...args);
|
|
} else {
|
|
// Otherwise, schedule execution for when the delay has passed
|
|
timeoutId.value = setTimeout(() => {
|
|
lastExecution.value = Date.now();
|
|
fn(...args);
|
|
timeoutId.value = null;
|
|
}, delay - elapsed);
|
|
}
|
|
};
|
|
};
|
|
|
|
export default useDebounceFn;
|