vue3+ts+pinia仿拼多多搜索页面代码实现
时间: 2023-09-03 17:07:08 浏览: 157
很高兴能为您提供帮助,下面是一个基于Vue3+TypeScript+Pinia实现的仿拼多多搜索页面的示例代码:
```vue
<template>
<div class="search-page">
<div class="search-bar">
<input type="text" v-model="query" placeholder="请输入搜索内容" />
<button @click="search">搜索</button>
</div>
<div class="search-result">
<div v-if="loading" class="loading">加载中...</div>
<div v-else-if="error" class="error">加载失败,请稍后重试</div>
<div v-else-if="result.length === 0" class="empty">暂无搜索结果</div>
<ul v-else>
<li v-for="(item, index) in result" :key="index">
<img :src="item.image" />
<div class="item-info">
<div class="item-title">{{ item.title }}</div>
<div class="item-price">{{ item.price }}</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useSearchStore } from '@/store/search'
import { SearchItem } from '@/types/search'
export default defineComponent({
name: 'SearchPage',
setup() {
const searchStore = useSearchStore()
const query = searchStore.query
const result = searchStore.result
const loading = searchStore.loading
const error = searchStore.error
const search = () => {
searchStore.search()
}
return {
query,
result,
loading,
error,
search
}
}
})
</script>
<style scoped>
.search-page {
padding: 20px;
}
.search-bar {
display: flex;
align-items: center;
margin-bottom: 20px;
input {
flex: 1;
height: 40px;
border: 1px solid #ccc;
border-radius: 4px;
padding: 0 10px;
font-size: 16px;
outline: none;
}
button {
height: 40px;
margin-left: 10px;
padding: 0 20px;
border-radius: 4px;
background-color: #f60;
color: #fff;
cursor: pointer;
outline: none;
border: none;
font-size: 16px;
}
}
.search-result {
ul {
display: flex;
flex-wrap: wrap;
}
li {
display: flex;
align-items: center;
width: 25%;
margin-bottom: 20px;
img {
width: 100%;
height: 200px;
object-fit: cover;
}
.item-info {
padding: 10px;
.item-title {
font-size: 16px;
margin-bottom: 10px;
}
.item-price {
font-size: 18px;
color: #f60;
}
}
}
.loading,
.error,
.empty {
text-align: center;
font-size: 20px;
margin-top: 50px;
}
}
</style>
```
在上面的代码中,我们利用Pinia状态管理库来管理搜索页面的状态,包括输入框的值、搜索结果、加载状态和错误状态等。具体实现流程如下:
1. 定义一个SearchStore,用来管理搜索页面的状态:
```ts
import { defineStore } from 'pinia'
import { SearchItem } from '@/types/search'
export const useSearchStore = defineStore('search', {
state: () => ({
query: '',
result: [] as SearchItem[],
loading: false,
error: false
}),
actions: {
async search() {
try {
this.loading = true
this.error = false
const result = await searchApi(this.query) // 调用搜索接口
this.result = result
} catch (error) {
this.error = true
} finally {
this.loading = false
}
}
}
})
```
2. 在SearchPage组件中使用SearchStore,并通过computed属性获取SearchStore中的状态和方法:
```ts
import { defineComponent } from 'vue'
import { useSearchStore } from '@/store/search'
import { SearchItem } from '@/types/search'
export default defineComponent({
name: 'SearchPage',
setup() {
const searchStore = useSearchStore()
const query = searchStore.query
const result = searchStore.result
const loading = searchStore.loading
const error = searchStore.error
const search = () => {
searchStore.search()
}
return {
query,
result,
loading,
error,
search
}
}
})
```
3. 在模板中使用获取到的状态和方法进行页面渲染和搜索操作:
```vue
<template>
<div class="search-page">
<div class="search-bar">
<input type="text" v-model="query" placeholder="请输入搜索内容" />
<button @click="search">搜索</button>
</div>
<div class="search-result">
<div v-if="loading" class="loading">加载中...</div>
<div v-else-if="error" class="error">加载失败,请稍后重试</div>
<div v-else-if="result.length === 0" class="empty">暂无搜索结果</div>
<ul v-else>
<li v-for="(item, index) in result" :key="index">
<img :src="item.image" />
<div class="item-info">
<div class="item-title">{{ item.title }}</div>
<div class="item-price">{{ item.price }}</div>
</div>
</li>
</ul>
</div>
</div>
</template>
```
实现了以上代码后,我们就可以在Vue3+TypeScript+Pinia的环境下,仿照拼多多实现搜索页面了。
阅读全文