vue实现模糊搜索
实现模糊搜索的基本思路
模糊搜索通常通过监听用户输入,对数据进行筛选匹配。Vue中可以利用计算属性或方法结合数组的filter和字符串的includes(或正则表达式)实现。
使用计算属性实现
通过计算属性动态过滤数据,依赖输入的关键字:
<template>
<input v-model="searchQuery" placeholder="搜索...">
<ul>
<li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li>
</ul>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
items: [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Orange' }
]
}
},
computed: {
filteredItems() {
return this.items.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}
}
}
</script>
使用方法实现
若需更复杂的逻辑(如异步请求),可在方法中处理:
methods: {
filterItems(query) {
return this.items.filter(item =>
item.name.toLowerCase().includes(query.toLowerCase())
)
}
}
支持多字段搜索
扩展计算属性,同时匹配多个字段:

computed: {
filteredItems() {
const query = this.searchQuery.toLowerCase()
return this.items.filter(item =>
item.name.toLowerCase().includes(query) ||
item.description.toLowerCase().includes(query)
)
}
}
使用正则表达式实现高级匹配
通过正则表达式实现更灵活的匹配(如忽略大小写、部分匹配):
computed: {
filteredItems() {
const regex = new RegExp(this.searchQuery, 'i')
return this.items.filter(item => regex.test(item.name))
}
}
结合第三方库(如Fuse.js)
对于大型数据集或复杂模糊搜索,可使用专用库:

-
安装Fuse.js:
npm install fuse.js -
在组件中使用:
import Fuse from 'fuse.js'
export default { data() { return { fuse: null, searchQuery: '', items: [/ 数据 /] } }, mounted() { this.fuse = new Fuse(this.items, { keys: ['name', 'description'], threshold: 0.4 }) }, computed: { filteredItems() { return this.searchQuery ? this.fuse.search(this.searchQuery).map(r => r.item) : this.items } } }
### 性能优化建议
- 对静态数据预建索引(如Fuse.js的`mounted`阶段)
- 使用防抖(lodash的`debounce`)避免频繁触发搜索
- 对于超大数据集考虑分页或虚拟滚动
### 完整示例代码
结合防抖和Fuse.js的完整实现:
```javascript
<template>
<input
v-model="searchQuery"
@input="onSearchInput"
placeholder="模糊搜索..."
>
<ul>
<li v-for="result in results" :key="result.id">
{{ result.name }} - {{ result.description }}
</li>
</ul>
</template>
<script>
import _ from 'lodash'
import Fuse from 'fuse.js'
export default {
data() {
return {
searchQuery: '',
items: [/* 原始数据 */],
fuse: null,
results: []
}
},
mounted() {
this.fuse = new Fuse(this.items, {
keys: ['name', 'description'],
includeScore: true,
threshold: 0.4
})
this.results = [...this.items]
},
methods: {
onSearchInput: _.debounce(function() {
this.results = this.searchQuery
? this.fuse.search(this.searchQuery).map(r => r.item)
: [...this.items]
}, 300)
}
}
</script>






