vue实现input动态搜索
Vue 实现动态搜索功能
使用 Vue 实现动态搜索功能通常涉及监听输入框变化、发送异步请求和展示结果。以下是几种常见实现方式:
使用 v-model 和 watch
<template>
<div>
<input v-model="searchQuery" placeholder="Search..." />
<ul v-if="results.length">
<li v-for="result in results" :key="result.id">
{{ result.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
results: [],
timeout: null
}
},
watch: {
searchQuery(newVal) {
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.performSearch(newVal)
}, 300)
}
},
methods: {
async performSearch(query) {
if (query.length < 2) {
this.results = []
return
}
const response = await fetch(`/api/search?q=${query}`)
this.results = await response.json()
}
}
}
</script>
使用计算属性
<template>
<div>
<input v-model="searchQuery" placeholder="Search..." />
<ul v-if="filteredItems.length">
<li v-for="item in filteredItems" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
items: [] // 从API获取或本地数据
}
},
computed: {
filteredItems() {
return this.items.filter(item =>
item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
)
}
}
}
</script>
使用自定义指令
<template>
<div>
<input v-model="searchQuery" v-debounce="onSearch" placeholder="Search..." />
<ul v-if="results.length">
<li v-for="result in results" :key="result.id">
{{ result.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
directives: {
debounce: {
inserted(el, binding) {
let timeout
el.addEventListener('input', () => {
clearTimeout(timeout)
timeout = setTimeout(() => {
binding.value(el.value)
}, 300)
})
}
}
},
data() {
return {
searchQuery: '',
results: []
}
},
methods: {
async onSearch(query) {
if (query.length < 2) {
this.results = []
return
}
const response = await fetch(`/api/search?q=${query}`)
this.results = await response.json()
}
}
}
</script>
使用第三方库
对于更复杂的需求,可以考虑使用 lodash 的 debounce 或 vue-use 的组合式 API:
<template>
<div>
<input v-model="searchQuery" placeholder="Search..." />
<ul v-if="results.length">
<li v-for="result in results" :key="result.id">
{{ result.name }}
</li>
</ul>
</div>
</template>
<script>
import { ref, watch } from 'vue'
import { useDebounceFn } from '@vueuse/core'
export default {
setup() {
const searchQuery = ref('')
const results = ref([])
const performSearch = useDebounceFn(async (query) => {
if (query.length < 2) {
results.value = []
return
}
const response = await fetch(`/api/search?q=${query}`)
results.value = await response.json()
}, 300)
watch(searchQuery, (newVal) => {
performSearch(newVal)
})
return { searchQuery, results }
}
}
</script>
性能优化建议
- 添加防抖(debounce)避免频繁请求
- 设置最小字符限制(如至少2个字符才搜索)
- 取消未完成的请求(使用AbortController)
- 添加加载状态和错误处理
- 考虑本地缓存结果
这些方法可以根据项目需求选择或组合使用,Vue 3的组合式API提供了更灵活的代码组织方式。







