vue 实现搜索联想
搜索联想功能的实现方法
在Vue中实现搜索联想功能,可以通过监听用户输入,实时向服务器发送请求获取匹配结果,并将结果显示在下拉列表中。
基本实现步骤
创建Vue组件,包含输入框和联想结果列表

<template>
<div class="search-container">
<input
v-model="searchQuery"
@input="handleInput"
@keydown.down="moveDown"
@keydown.up="moveUp"
@keydown.enter="selectItem"
placeholder="输入搜索内容"
/>
<ul v-show="showSuggestions" class="suggestions-list">
<li
v-for="(item, index) in suggestions"
:key="index"
:class="{ 'active': index === activeIndex }"
@click="selectItem"
>
{{ item }}
</li>
</ul>
</div>
</template>
组件逻辑实现
<script>
export default {
data() {
return {
searchQuery: '',
suggestions: [],
showSuggestions: false,
activeIndex: -1,
timeout: null
}
},
methods: {
handleInput() {
clearTimeout(this.timeout)
if(this.searchQuery.length < 2) {
this.suggestions = []
this.showSuggestions = false
return
}
this.timeout = setTimeout(() => {
this.fetchSuggestions()
}, 300)
},
async fetchSuggestions() {
try {
const response = await axios.get('/api/suggestions', {
params: { q: this.searchQuery }
})
this.suggestions = response.data
this.showSuggestions = this.suggestions.length > 0
this.activeIndex = -1
} catch (error) {
console.error('获取联想词失败:', error)
}
},
moveDown() {
if(this.activeIndex < this.suggestions.length - 1) {
this.activeIndex++
}
},
moveUp() {
if(this.activeIndex > 0) {
this.activeIndex--
}
},
selectItem() {
if(this.activeIndex >= 0) {
this.searchQuery = this.suggestions[this.activeIndex]
}
this.showSuggestions = false
// 执行搜索操作
this.$emit('search', this.searchQuery)
}
}
}
</script>
样式设计
<style scoped>
.search-container {
position: relative;
width: 300px;
}
.suggestions-list {
position: absolute;
width: 100%;
max-height: 200px;
overflow-y: auto;
border: 1px solid #ddd;
border-top: none;
background: white;
list-style: none;
padding: 0;
margin: 0;
z-index: 1000;
}
.suggestions-list li {
padding: 8px 12px;
cursor: pointer;
}
.suggestions-list li:hover, .suggestions-list li.active {
background-color: #f5f5f5;
}
</style>
性能优化方案
使用防抖技术减少请求频率
this.timeout = setTimeout(() => {
this.fetchSuggestions()
}, 300) // 300毫秒延迟
实现缓存机制避免重复请求

data() {
return {
cache: new Map()
}
},
methods: {
async fetchSuggestions() {
if(this.cache.has(this.searchQuery)) {
this.suggestions = this.cache.get(this.searchQuery)
this.showSuggestions = true
return
}
try {
const response = await axios.get('/api/suggestions', {
params: { q: this.searchQuery }
})
this.suggestions = response.data
this.cache.set(this.searchQuery, this.suggestions)
this.showSuggestions = this.suggestions.length > 0
} catch (error) {
console.error('获取联想词失败:', error)
}
}
}
高级功能扩展
添加高亮匹配文本功能
methods: {
highlightMatch(text) {
if(!this.searchQuery) return text
const regex = new RegExp(this.searchQuery, 'gi')
return text.replace(regex, match => `<span class="highlight">${match}</span>`)
}
}
添加节流滚动加载更多
mounted() {
const list = this.$el.querySelector('.suggestions-list')
list.addEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
const { scrollTop, scrollHeight, clientHeight } = this.$el.querySelector('.suggestions-list')
if(scrollTop + clientHeight >= scrollHeight - 10) {
this.loadMore()
}
},
loadMore() {
// 加载更多联想结果的逻辑
}
}






