58 lines
1.1 KiB
JavaScript
58 lines
1.1 KiB
JavaScript
import { getCurrentInstance, onUnmounted } from 'vue'
|
|
|
|
// 防抖
|
|
export function useDebounce(fn, delay = 500, immediate = false) {
|
|
let timer = null
|
|
let instance = getCurrentInstance() // 获取当前组件实例
|
|
|
|
const debounced = (...args) => {
|
|
if (timer) clearTimeout(timer)
|
|
|
|
if (immediate && !timer) {
|
|
// 立即执行
|
|
fn.apply(this, args)
|
|
}
|
|
|
|
timer = setTimeout(() => {
|
|
if (!immediate) fn.apply(this, args)
|
|
timer = null // 清理timer引用
|
|
}, delay)
|
|
}
|
|
|
|
// 取消防抖执行
|
|
debounced.cancel = () => {
|
|
clearTimeout(timer)
|
|
timer = null
|
|
}
|
|
|
|
// 立即执行
|
|
debounced.flush = (...args) => {
|
|
clearTimeout(timer)
|
|
timer = null
|
|
fn.apply(this, args)
|
|
}
|
|
|
|
if (instance) {
|
|
// 自动注册卸载钩子(仅组件内生效)
|
|
onUnmounted(() => {
|
|
debounced.cancel()
|
|
})
|
|
}
|
|
|
|
return debounced
|
|
}
|
|
|
|
// 节流
|
|
export function useThrottle(fn, delay = 1000) {
|
|
let lastCall = 0
|
|
|
|
const throttled = (...args) => {
|
|
const now = Date.now()
|
|
if (now - lastCall < delay) return
|
|
lastCall = now
|
|
fn(...args)
|
|
}
|
|
|
|
return throttled
|
|
}
|