vue实现搜索组件
实现搜索组件的基本结构
在Vue中实现搜索组件需要创建一个独立的组件,包含输入框和搜索按钮。以下是一个基础的模板结构:
<template>
<div class="search-container">
<input
type="text"
v-model="searchQuery"
placeholder="输入搜索内容..."
@keyup.enter="handleSearch"
/>
<button @click="handleSearch">搜索</button>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: ''
}
},
methods: {
handleSearch() {
this.$emit('search', this.searchQuery)
}
}
}
</script>
<style scoped>
.search-container {
display: flex;
gap: 10px;
}
</style>
添加防抖功能
为了防止频繁触发搜索请求,可以添加防抖功能:
import { debounce } from 'lodash'
export default {
data() {
return {
searchQuery: '',
debouncedSearch: debounce(this.emitSearch, 500)
}
},
methods: {
handleSearch() {
this.debouncedSearch()
},
emitSearch() {
this.$emit('search', this.searchQuery)
}
}
}
集成到父组件
在父组件中使用搜索组件并处理搜索事件:
<template>
<div>
<search-component @search="performSearch" />
<!-- 显示搜索结果 -->
<div v-if="searchResults.length">
<div v-for="result in searchResults" :key="result.id">
{{ result.title }}
</div>
</div>
</div>
</template>
<script>
import SearchComponent from './SearchComponent.vue'
export default {
components: {
SearchComponent
},
data() {
return {
searchResults: []
}
},
methods: {
async performSearch(query) {
try {
const response = await fetch(`/api/search?q=${query}`)
this.searchResults = await response.json()
} catch (error) {
console.error('搜索失败:', error)
}
}
}
}
</script>
添加搜索建议
实现搜索建议功能可以提升用户体验:
<template>
<div class="search-container">
<input
type="text"
v-model="searchQuery"
@input="fetchSuggestions"
@focus="showSuggestions = true"
@blur="hideSuggestions"
/>
<ul v-if="showSuggestions && suggestions.length" class="suggestions">
<li
v-for="suggestion in suggestions"
:key="suggestion"
@mousedown="selectSuggestion(suggestion)"
>
{{ suggestion }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
suggestions: [],
showSuggestions: false
}
},
methods: {
async fetchSuggestions() {
if (this.searchQuery.length > 2) {
const response = await fetch(`/api/suggestions?q=${this.searchQuery}`)
this.suggestions = await response.json()
}
},
selectSuggestion(suggestion) {
this.searchQuery = suggestion
this.showSuggestions = false
this.handleSearch()
},
hideSuggestions() {
setTimeout(() => {
this.showSuggestions = false
}, 200)
}
}
}
</script>
<style scoped>
.suggestions {
position: absolute;
list-style: none;
padding: 0;
margin: 0;
background: white;
border: 1px solid #ddd;
width: 100%;
max-height: 200px;
overflow-y: auto;
}
.suggestions li {
padding: 8px;
cursor: pointer;
}
.suggestions li:hover {
background-color: #f5f5f5;
}
</style>
高级搜索功能
对于更复杂的搜索需求,可以实现高级搜索选项:
<template>
<div>
<input v-model="searchQuery" placeholder="基本搜索" />
<button @click="toggleAdvanced">高级搜索</button>
<div v-if="showAdvanced" class="advanced-search">
<input v-model="filters.author" placeholder="作者" />
<input v-model="filters.date" type="date" placeholder="日期" />
<select v-model="filters.category">
<option value="">所有分类</option>
<option v-for="cat in categories" :value="cat.id">{{ cat.name }}</option>
</select>
</div>
<button @click="handleSearch">搜索</button>
</div>
</template>
<script>
export default {
data() {
return {
searchQuery: '',
showAdvanced: false,
filters: {
author: '',
date: '',
category: ''
},
categories: []
}
},
created() {
this.fetchCategories()
},
methods: {
toggleAdvanced() {
this.showAdvanced = !this.showAdvanced
},
async fetchCategories() {
const response = await fetch('/api/categories')
this.categories = await response.json()
},
handleSearch() {
const searchParams = {
q: this.searchQuery,
...this.filters
}
this.$emit('search', searchParams)
}
}
}
</script>
响应式设计优化
确保搜索组件在不同设备上都能良好显示:
.search-container {
display: flex;
flex-direction: column;
gap: 10px;
}
@media (min-width: 768px) {
.search-container {
flex-direction: row;
}
}
input {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
width: 100%;
}
button {
padding: 8px 16px;
background-color: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
这些实现方法涵盖了从基础到高级的搜索组件功能,可以根据具体需求进行选择和组合。







