watcheffect 可实现搜索框“输入即搜”,自动追踪 searchkey 并触发请求;需手动加防抖、空值校验和请求取消机制以优化体验。

watchEffect 是 Vue 3 中一个响应式副作用函数,它会自动追踪内部读取的响应式数据,并在这些数据变化时重新执行。用它实现搜索框的“输入即搜”,比手动监听 input 事件 + 防抖更简洁(但要注意:默认无防抖,高频输入可能触发过多请求)。
基础用法:监听搜索关键词并触发请求
假设你有一个响应式搜索关键词 searchKey(比如用 ref 定义),直接在 setup 中使用 watchEffect:
import { ref, watchEffect } from 'vue'
export default {
setup() {
const searchKey = ref('')
const searchResults = ref([])
watchEffect(async (onCleanup) => {
// 若关键词为空,可提前退出,避免无效请求
if (!searchKey.value.trim()) {
searchResults.value = []
return
}
// 可选:取消上一次未完成的请求(需配合 onCleanup)
let isCancelled = false
onCleanup(() => {
isCancelled = true
})
try {
const res = await fetch(`/api/search?q=${encodeURIComponent(searchKey.value)}`)
if (!isCancelled) {
searchResults.value = await res.json()
}
} catch (err) {
if (!isCancelled) {
console.error('搜索失败', err)
}
}
})
return { searchKey, searchResults }
}
}
搭配输入框:v-model 绑定即可自动响应
模板中只需普通绑定,无需额外事件处理:
<input v-model="searchKey" placeholder="输入关键词搜索...">
- {{ item.title }}
因为 v-model 会更新 searchKey.value,而 watchEffect 自动追踪了它,所以每次输入都会触发副作用函数。
加防抖:避免频繁请求(推荐生产环境使用)
watchEffect 本身不支持防抖,但你可以用 setTimeout + onCleanup 模拟:
watchEffect((onCleanup) => {
const value = searchKey.value.trim()
if (!value) {
searchResults.value = []
return
}
const timer = setTimeout(async () => {
try {
const res = await fetch(`/api/search?q=${encodeURIComponent(value)}`)
searchResults.value = await res.json()
} catch (err) {
console.error(err)
}
}, 300) // 300ms 防抖
onCleanup(() => clearTimeout(timer))
})
注意点和优化建议
- 避免空格或纯空白字符触发搜索:用
.trim()判断 - 网络请求失败时要有兜底处理(如清空结果、显示错误提示)
- 如果搜索逻辑较重,可结合
computed或debouncedRef(VueUse 提供)进一步封装 - 服务端需支持快速响应,否则用户连续输入仍可能看到旧结果(可用
isCancelled机制拦截)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










