应使用 watch 配合手写防抖实现输入框实时搜索:监听 keyword 变化,每次清除旧定时器并设置新 setTimeout(300–500ms),在 doSearch 中校验非空、去空格、长度达标,组件卸载前清除定时器防泄漏。

用 watch 实现输入框实时搜索本身很简单,但不加防抖极易引发性能问题——比如每按一个键就发请求,用户快速输入时可能触发十几次无意义的 API 调用。关键不是“能不能监听”,而是“什么时候才该响应”。下面从原理到落地,讲清楚怎么写一个真正可用的带防抖的实时搜索。
watch 监听输入值,但不直接发起请求
监听 inputValue 的变化是基础,但 watch 回调里只做一件事:重置/启动防抖计时器。不要在 watch 里直接调用 search() 或 fetchData()。
- 使用
ref或reactive定义搜索关键词(如const keyword = ref('')) - watch 的回调中清除上一次定时器(如有),再设置新的延时执行逻辑
- 延时时间建议 300–500ms,太短起不到防抖作用,太长影响响应感
用 setTimeout 手写防抖,避免依赖额外库
不需要引入 lodash,几行代码就能实现可靠防抖。核心是维护一个定时器引用,在每次输入时清空旧的、设置新的。
- 定义一个响应式变量
let timer = null(注意:不能用ref(null)存定时器 ID,因为 clearTimeout 接收的是原始数字) - watch 回调中:
if (timer) clearTimeout(timer); timer = setTimeout(() => { doSearch(keyword.value); }, 300); - 组件卸载前(onBeforeUnmount)记得
clearTimeout(timer),防止内存泄漏
搜索前加基础校验,减少无效请求
防抖解决的是“频次”问题,但还要避免“无意义”请求——比如空字符串、纯空格、过短关键词。
- 在
doSearch函数开头判断:if (!keyword.value?.trim() || keyword.value.trim().length - 对关键词做
.trim()再发送,避免前后空格导致后端匹配失败 - 可选:添加 loading 状态控制按钮/列表显示,提升交互反馈
进阶:结合 v-model.lazy 或搜索按钮保底体验
纯实时搜索对网络和后端压力大,实际项目中建议保留“回车搜索”或“搜索按钮”作为补充路径。
- 输入框绑定
@keyup.enter="doSearch",让用户主动确认 - 按钮点击调用同一
doSearch,内部仍走防抖逻辑(避免重复提交) - 这样既满足“想输就搜”的便捷性,又给用户明确的控制权


















