vue实现搜索功能
实现搜索功能的基本思路
在Vue中实现搜索功能通常需要结合数据绑定、事件监听和过滤逻辑。可以通过计算属性或方法对数据进行实时筛选。
使用计算属性实现搜索
通过v-model绑定搜索输入框,利用计算属性过滤数据列表:
<template>
<div>
<input v-model="searchQuery" placeholder="搜索...">
<ul>
<li v-for="item in filteredItems" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
items: [
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' },
{ id: 3, name: '橙子' }
]
}
},
computed: {
filteredItems() {
return this.items.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}
}
}
</script>
使用watch实现异步搜索
当需要从API异步获取搜索结果时,可以使用watch配合防抖:
<script>
import debounce from 'lodash.debounce'
export default {
data() {
return {
searchQuery: '',
results: [],
isLoading: false
}
},
watch: {
searchQuery: debounce(function(newVal) {
if (newVal) {
this.fetchResults(newVal)
} else {
this.results = []
}
}, 500)
},
methods: {
async fetchResults(query) {
this.isLoading = true
try {
const response = await axios.get(`/api/search?q=${query}`)
this.results = response.data
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
}
}
}
}
</script>
使用第三方库实现高级搜索
对于更复杂的搜索需求,可以考虑使用专用搜索库如Fuse.js:
import Fuse from 'fuse.js'
export default {
data() {
return {
fuse: null,
searchQuery: '',
items: [...],
searchResults: []
}
},
mounted() {
this.fuse = new Fuse(this.items, {
keys: ['name', 'description'],
threshold: 0.4
})
},
watch: {
searchQuery(val) {
this.searchResults = val ? this.fuse.search(val) : this.items
}
}
}
添加搜索建议功能
实现搜索框自动完成建议:
<template>
<div class="search-container">
<input
v-model="searchQuery"
@input="handleInput"
@focus="showSuggestions = true"
@blur="hideSuggestions"
>
<ul v-show="showSuggestions && suggestions.length">
<li
v-for="suggestion in suggestions"
:key="suggestion.id"
@mousedown="selectSuggestion(suggestion)"
>
{{ suggestion.text }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
showSuggestions: false,
suggestions: []
}
},
methods: {
handleInput() {
if (this.searchQuery.length > 1) {
this.fetchSuggestions(this.searchQuery)
} else {
this.suggestions = []
}
},
hideSuggestions() {
setTimeout(() => {
this.showSuggestions = false
}, 200)
},
selectSuggestion(suggestion) {
this.searchQuery = suggestion.text
this.showSuggestions = false
}
}
}
</script>
样式优化建议
为搜索组件添加基础样式:
.search-container {
position: relative;
width: 300px;
}
.search-container input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.search-container ul {
position: absolute;
width: 100%;
margin: 0;
padding: 0;
list-style: none;
background: white;
border: 1px solid #eee;
max-height: 200px;
overflow-y: auto;
}
.search-container li {
padding: 8px;
cursor: pointer;
}
.search-container li:hover {
background-color: #f5f5f5;
}






