ref管理搜索过滤关键字的核心是作为响应式输入源,配合computed实现本地缓存过滤或watch结合AbortController处理防抖/竞态的远程搜索,支持单关键词或多字段独立筛选。

用 ref 管理搜索过滤关键字,核心是把它作为响应式输入源,配合计算属性或 watch 实时驱动过滤逻辑。它轻量、直观,适合单关键词或多个独立搜索字段的场景。
ref 定义搜索关键词并绑定到输入框
直接用 ref 创建一个字符串响应式变量,通过 v-model 双向绑定到 <input>,输入即更新值:
import { ref } from 'vue'
const keyword = ref('')模板中:
<input v-model="keyword" placeholder="搜索名称或分类..." />
Vue 会自动解包 .value,无需在模板里写 keyword.value。
立即学习“前端免费学习笔记(深入)”;
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
ref 配合 computed 实现本地过滤
当数据量不大、过滤逻辑简单(如前端列表筛选),把 keyword 传入 computed 最简洁:
- 自动响应变化
- 结果缓存,避免重复计算
- 支持空值判断和大小写归一化
示例:
const filteredList = computed(() => {
if (!keyword.value.trim()) return originalList.value
const kw = keyword.value.toLowerCase()
return originalList.value.filter(item =>
item.name.toLowerCase().includes(kw) ||
item.category.toLowerCase().includes(kw)
)
})ref 配合 watch 处理远程搜索(带防抖/取消)
如果每次输入都触发 API 请求,需用 watch 监听 keyword,但必须处理竞态问题:
- 快速输入时,后发请求可能先返回,覆盖正确结果
- 推荐用
AbortController主动中止上一次请求
import { ref, watch } from 'vue'
const keyword = ref('')
const list = ref([])
let controller: AbortController | null = null
watch(keyword, async (val) => {
if (!val.trim()) {
list.value = []
return
}
if (controller) controller.abort()
controller = new AbortController()
try {
const res = await fetch(`/api/items?q=${encodeURIComponent(val)}`, {
signal: controller.signal
})
list.value = await res.json()
} catch (err) {
if (err.name !== 'AbortError') {
console.error('搜索请求失败:', err)
}
}
})多个搜索条件共存时用多个 ref
例如同时按 ID、昵称、手机号筛选,每个字段独立 ref,再在 computed 或 watch 中组合判断:
const searchId = ref('')
const searchNickname = ref('')
const searchTel = ref('')
const filteredData = computed(() => {
return rawData.value.filter(item => {
const matchId = !searchId.value || item.id.toString().includes(searchId.value)
const matchNick = !searchNickname.value ||
item.nickname.toLowerCase().includes(searchNickname.value.toLowerCase())
const matchTel = !searchTel.value || item.tel.includes(searchTel.value)
return matchId && matchNick && matchTel
})
})

















