← [ BACK_TO_NOTES ]

防抖节流封装模式

VueUse 风格的防抖与节流函数封装

#frontend #concept #evergreen

[!info] related notes

防抖节流封装模式

[!note] 角色边界 本篇只维护 Vue/Composable 风格的实现模板;“什么时候用防抖、什么时候用节流”以及两者机制差异由 防抖与节流 维护。

前端性能优化:防抖(debounce)与节流(throttle)的 Vue 3 封装

VueUse 风格的防抖封装

// composables/useDebounce.ts
import { ref, watch, unref, type Ref } from 'vue'

export const useDebounceFn = <T extends (...args: any[]) => any>(
  fn: T,
  delay = 300
) => {
  let timer: ReturnType<typeof setTimeout> | null = null

  const debouncedFn = (...args: Parameters<T>) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(...args)
    }, delay)
  }

  const cancel = () => {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
  }

  return { debouncedFn, cancel }
}

export const useDebounce = <T>(value: Ref<T>, delay = 300) => {
  const debounced = ref(unref(value)) as Ref<T>

  let timer: ReturnType<typeof setTimeout> | null = null

  watch(value, (newValue) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      debounced.value = newValue
    }, delay)
  })

  return debounced
}

// 使用示例
const searchText = ref('')
const debouncedSearch = useDebounce(searchText, 500)

watch(debouncedSearch, (value) => {
  // 只有在用户停止输入 500ms 后才触发搜索
  performSearch(value)
})

// 防抖函数
const { debouncedFn } = useDebounceFn(handleSearch, 500)

节流封装

// composables/useThrottle.ts
export const useThrottleFn = <T extends (...args: any[]) => any>(
  fn: T,
  delay = 300
) => {
  let lastTime = 0

  const throttledFn = (...args: Parameters<T>) => {
    const now = Date.now()
    if (now - lastTime >= delay) {
      lastTime = now
      fn(...args)
    }
  }

  return { throttledFn }
}

// 使用示例 - 滚动加载
const { throttledFn: handleScroll } = useThrottleFn(() => {
  const scrollTop = document.documentElement.scrollTop
  const clientHeight = document.documentElement.clientHeight
  const scrollHeight = document.documentElement.scrollHeight

  if (scrollTop + clientHeight >= scrollHeight - 100) {
    loadMore()
  }
}, 200)

onMounted(() => {
  window.addEventListener('scroll', handleScroll)
})

onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll)
})

优雅之处:

  • 提升性能,避免频繁触发
  • 改善用户体验(搜索、滚动)
  • 可取消的防抖

创建于 2026/5/27 更新于 2026/7/15
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本