vue实现搜索
vue实现搜索功能
使用v-model绑定输入框
在Vue中可以通过v-model指令实现输入框与数据的双向绑定。创建一个搜索输入框,将用户输入的内容实时绑定到Vue实例的data属性中。
<template>
<div>
<input v-model="searchQuery" placeholder="搜索..." />
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: ''
}
}
}
</script>
计算属性过滤数据
使用计算属性对数据进行过滤。计算属性会根据searchQuery的变化自动重新计算,返回过滤后的结果。
<script>
export default {
data() {
return {
searchQuery: '',
items: [
{ name: '苹果' },
{ name: '香蕉' },
{ name: '橙子' }
]
}
},
computed: {
filteredItems() {
return this.items.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}
}
}
</script>
显示搜索结果
在模板中遍历计算属性返回的过滤结果,显示搜索匹配的内容。
<template>
<div>
<input v-model="searchQuery" placeholder="搜索..." />
<ul>
<li v-for="item in filteredItems" :key="item.name">
{{ item.name }}
</li>
</ul>
</div>
</template>
添加防抖优化性能
对于频繁触发的搜索输入,可以添加防抖函数来优化性能,减少不必要的计算。
<script>
export default {
data() {
return {
searchQuery: '',
items: [...],
debounceTimeout: null
}
},
computed: {
filteredItems() {
clearTimeout(this.debounceTimeout)
return new Promise(resolve => {
this.debounceTimeout = setTimeout(() => {
resolve(this.items.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
))
}, 300)
})
}
}
}
</script>
调用API实现远程搜索
对于需要从服务器获取搜索结果的场景,可以在watch中监听searchQuery的变化,调用API获取数据。
<script>
export default {
data() {
return {
searchQuery: '',
searchResults: []
}
},
watch: {
searchQuery(newVal) {
if(newVal.length > 2) {
this.fetchSearchResults(newVal)
}
}
},
methods: {
async fetchSearchResults(query) {
try {
const response = await axios.get(`/api/search?q=${query}`)
this.searchResults = response.data
} catch (error) {
console.error('搜索出错:', error)
}
}
}
}
</script>
添加加载状态和空状态
为了提高用户体验,可以添加加载状态和没有搜索结果时的提示。
<template>
<div>
<input v-model="searchQuery" placeholder="搜索..." />
<div v-if="isLoading">搜索中...</div>
<div v-else-if="filteredItems.length === 0">没有找到匹配的结果</div>
<ul v-else>
<li v-for="item in filteredItems" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
isLoading: false,
items: [...]
}
}
}
</script>






