搜索功能在电商领域是非常常见的一个功能具体表现在两个方面:
对用户来说,生鲜电商类的搜索功能通常是用来解决“快速找到满意的商品”的问题。“快速找到满意的商品”中的“快速”和“满意”是关键词,但二者其实在很大程度上是矛盾的。一方面“快速”意味着用户的搜索操作应尽量方便、快捷,也就是要求平台应当尽量少的让用户交互提供信息;但另一方面,“满意”通常又意味着平台需要尽量多的与用户交互。毕竟,平台上的商品数以万计,只有更多的获取用户信息才能更好的明白客户到底想买什么。
对平台来说,在产品设计过程中,还应当充分考虑平台“充分利用流量号召用户产生更多购买意向”的需求。
<template>
<view class="my-search-container" :style="{ 'background-color': bgcolor }" @click="searchBoxHandler">
<view class="my-search-box" :style="{ 'border-radius': radius + 'px' }">
<!-- 使用 uni-ui 提供的图标组件 -->
<uni-icons type="search" size="17"></uni-icons>
<text class="placeholder">搜索</text>
</view>
</view>
</template>
<script>
export default {
props: {
// 背景颜色
bgcolor: {
type: String,
default: '#C00000'
},
// 圆角尺寸
radius: {
type: Number,
default: 18 // px
}
},
data() {
return {
}
},
methods: {
searchBoxHandler() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
.my-search-container {
height: 50px;
// background-color: #C00000;
display: flex;
align-items: center;
padding: 0 10px;
.my-search-box {
height: 36px;
background-color: #FFFFFF;
// border-radius: 18px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
.placeholder {
font-size: 15px;
margin-left: 5px;
}
}
}
</style>
<template>
<view>
<view class="search-box">
<uni-search-bar @input="input" :radius="100" cancelButton="none"></uni-search-bar>
</view>
<!-- 搜索建议列表 -->
<view class="sugg-list" v-if="searchResults.length !== 0">
<view class="sugg-item" v-for="(item, i) in searchResults" :key="i" @click="gotoDetail(item)">
<view class="goods-name">{{item.goods_name}}</view>
<uni-icons type="arrowright" size="16"></uni-icons>
</view>
</view>
<!-- 搜索历史 -->
<view class="history-box" v-else>
<!-- 标题区域 -->
<view class="history-title">
<text>搜索历史</text>
<uni-icons type="trash" size="17" @click="clean"></uni-icons>
</view>
<!-- 列表区域 -->
<view class="history-list">
<uni-tag :text="item" v-for="(item, i) in histories" :key="i" @click="gotoGoodsList(item)"></uni-tag>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
timer: null,
kw: '',
// 搜索的结果列表
searchResults: [],
// 搜索历史的数组
historyList: []
};
},
onLoad() {
this.historyList = JSON.parse(uni.getStorageSync('kw') || '[]')
},
methods: {
// input 输入事件的处理函数
input(e) {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.kw = e.value
this.getSearchList()
}, 500)
},
async getSearchList() {
// 判断搜索关键词是否为空
if (this.kw.length === 0) {
this.searchResults = []
return
}
const { data: res } = await uni.$http.get('/api/public/v1/goods/qsearch', { query: this.kw })
if (res.meta.status !== 200) return uni.$showMsg()
this.searchResults = res.message
this.saveSearchHistory()
},
gotoDetail(item) {
uni.navigateTo({
url: '/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id
})
},
saveSearchHistory() {
// this.historyList.push(this.kw)
const set = new Set(this.historyList)
set.delete(this.kw)
set.add(this.kw)
this.historyList = Array.from(set)
// 对搜索历史数据,进行持久化的存储
uni.setStorageSync('kw', JSON.stringify(this.historyList))
},
clean() {
this.historyList = []
uni.setStorageSync('kw', '[]')
},
gotoGoodsList(kw) {
uni.navigateTo({
url: '/subpkg/goods_list/goods_list?query=' + kw
})
}
},
computed: {
histories() {
return [...this.historyList].reverse()
}
}
}
</script>
<style lang="scss">
.search-box {
position: sticky;
top: 0;
z-index: 999;
}
.sugg-list {
padding: 0 5px;
.sugg-item {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
padding: 13px 0;
border-bottom: 1px solid #efefef;
.goods-name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 3px;
}
}
}
.history-box {
padding: 0 5px;
.history-title {
display: flex;
justify-content: space-between;
height: 40px;
align-items: center;
font-size: 13px;
border-bottom: 1px solid #efefef;
}
.history-list {
display: flex;
flex-wrap: wrap;
.uni-tag {
margin-top: 5px;
margin-right: 5px;
}
}
}
</style>