vue实现菜单搜索
实现思路
在Vue中实现菜单搜索功能,通常需要结合输入框的实时监听、菜单数据的过滤以及结果的动态展示。核心逻辑包括监听用户输入、过滤菜单数据、高亮匹配关键词。
基本实现步骤
创建搜索输入框
在模板中添加一个输入框组件,用于接收用户输入的关键词。使用v-model双向绑定搜索关键词。
<template>
<div>
<input v-model="searchQuery" placeholder="搜索菜单..." />
<ul>
<li v-for="item in filteredMenu" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
定义菜单数据和搜索关键词
在Vue的data或setup中定义菜单数据和搜索关键词的响应式变量。
data() {
return {
searchQuery: '',
menuItems: [
{ id: 1, name: '首页' },
{ id: 2, name: '产品列表' },
{ id: 3, name: '关于我们' }
]
}
}
计算过滤后的菜单
使用computed属性根据搜索关键词动态过滤菜单项。过滤逻辑通常包括不区分大小写和部分匹配。
computed: {
filteredMenu() {
const query = this.searchQuery.toLowerCase()
return this.menuItems.filter(item =>
item.name.toLowerCase().includes(query)
)
}
}
高级功能扩展
添加防抖优化 频繁输入可能导致性能问题,可以通过防抖函数优化搜索触发频率。
methods: {
debounceSearch: _.debounce(function() {
this.filteredMenu = this.menuItems.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}, 300)
}
高亮匹配文本
在渲染菜单时,使用正则表达式将匹配部分包裹在<span>标签中并添加高亮样式。
<li v-for="item in filteredMenu" :key="item.id" v-html="highlight(item.name)">
</li>
methods: {
highlight(text) {
const query = this.searchQuery
if (!query) return text
return text.replace(new RegExp(query, 'gi'), match =>
`<span class="highlight">${match}</span>`
)
}
}
完整示例代码
<template>
<div>
<input
v-model="searchQuery"
@input="debounceSearch"
placeholder="搜索菜单..."
/>
<ul>
<li
v-for="item in filteredMenu"
:key="item.id"
v-html="highlight(item.name)"
></li>
</ul>
</div>
</template>
<script>
import _ from 'lodash'
export default {
data() {
return {
searchQuery: '',
menuItems: [
{ id: 1, name: '首页' },
{ id: 2, name: '产品列表' },
{ id: 3, name: '关于我们' }
],
filteredMenu: []
}
},
created() {
this.filteredMenu = this.menuItems
},
methods: {
debounceSearch: _.debounce(function() {
this.filteredMenu = this.menuItems.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}, 300),
highlight(text) {
const query = this.searchQuery
if (!query) return text
return text.replace(new RegExp(query, 'gi'), match =>
`<span class="highlight">${match}</span>`
)
}
}
}
</script>
<style>
.highlight {
background-color: yellow;
font-weight: bold;
}
</style>
注意事项
- 对于大型菜单数据,考虑使用Web Worker进行后台过滤以避免界面卡顿
- 如果菜单数据来自API,需要在获取数据后初始化过滤逻辑
- 移动端需要优化输入体验,可以考虑增加清除按钮和搜索图标







