使用vue实现模糊查询
实现模糊查询的基本思路
在Vue中实现模糊查询通常需要结合输入框的监听、数据处理和过滤逻辑。核心步骤包括监听用户输入、处理输入内容、过滤数据列表以及渲染结果。
监听用户输入
使用v-model双向绑定输入框的值,配合@input或watch监听输入变化:
<template>
<input v-model="searchText" placeholder="输入关键词搜索" />
</template>
<script>
export default {
data() {
return {
searchText: "",
rawData: ["苹果", "香蕉", "橙子", "西瓜"], // 原始数据
filteredData: [] // 过滤后的结果
};
},
watch: {
searchText(newVal) {
this.filterData(newVal);
}
}
};
</script>
实现过滤逻辑
使用JavaScript的字符串方法或正则表达式进行模糊匹配。常见方法包括includes()、indexOf()或正则表达式的test():
methods: {
filterData(keyword) {
if (!keyword) {
this.filteredData = [...this.rawData];
return;
}
this.filteredData = this.rawData.filter(item =>
item.toLowerCase().includes(keyword.toLowerCase())
);
}
}
渲染过滤结果
通过v-for展示过滤后的数据列表:
<template>
<ul>
<li v-for="(item, index) in filteredData" :key="index">
{{ item }}
</li>
</ul>
</template>
使用计算属性优化性能
对于小型数据集,可以用计算属性替代watch,避免手动触发过滤:
computed: {
filteredData() {
const keyword = this.searchText.toLowerCase();
return this.rawData.filter(item =>
item.toLowerCase().includes(keyword)
);
}
}
高级模糊搜索(正则表达式)
如果需要更灵活的匹配(如忽略大小写、部分匹配),可使用正则表达式:
methods: {
filterData(keyword) {
const regex = new RegExp(keyword, 'i'); // 'i'表示忽略大小写
this.filteredData = this.rawData.filter(item => regex.test(item));
}
}
结合第三方库(如Fuse.js)
对于复杂场景(如权重匹配、错别字容错),可使用模糊搜索库:
-
安装Fuse.js:
npm install fuse.js -
在Vue中使用:
import Fuse from 'fuse.js';
export default { data() { return { fuse: null, options: { // 配置搜索选项 keys: ['name'], // 搜索的字段 threshold: 0.4 // 匹配阈值 } }; }, created() { this.fuse = new Fuse(this.rawData, this.options); }, methods: { filterData(keyword) { this.filteredData = keyword ? this.fuse.search(keyword).map(r => r.item) : [...this.rawData]; } } };
### 处理异步数据
如果数据来自API请求,需在获取数据后初始化搜索逻辑:
```javascript
async created() {
const res = await axios.get('/api/data');
this.rawData = res.data;
this.filteredData = [...this.rawData];
}
防抖优化性能
频繁输入时通过防抖减少计算次数:
import { debounce } from 'lodash';
methods: {
filterData: debounce(function(keyword) {
// 过滤逻辑
}, 300)
}
样式与交互增强
添加加载状态和空结果提示:
<template>
<div v-if="loading">搜索中...</div>
<div v-else-if="filteredData.length === 0">无匹配结果</div>
</template>






