搜索建议
1 渲染搜索页面的基本结构
- 定义如下的 UI 结构:
<view class="search-box">
<!-- 使用 uni-ui 提供的搜索组件 -->
<uni-search-bar @input="input" :radius="100" cancelButton="none"></uni-search-bar>
</view>
:focus="true"
自动聚焦
- 修改
components -> uni-search-bar -> uni-search-bar.vue
组件,将默认的白色搜索背景改为#C00000
的红色背景:
-
实现搜索框的吸顶效果:
-
定义如下的 input 事件处理函数:
methods: { input(e) { // e.value 是最新的搜索内容 console.log(e) } }
2 防抖
-
在 data 中定义防抖的延时器 timerId 如下:
data() { return { // 延时器的 timerId timer: null, // 搜索关键词 kw: '' } }
-
修改
input
事件处理函数如下:input(e) { // 清除 timer 对应的延时器 clearTimeout(this.timer) // 重新启动一个延时器,并把 timerId 赋值给 this.timer this.timer = setTimeout(() => { // 如果 500 毫秒内,没有触发新的输入事件,则为搜索关键词赋值 this.kw = e console.log(this.kw) }, 500) }
3 根据关键词查询搜索建议列表
-
在 data 中定义如下的数据节点,用来存放搜索建议的列表数据:
data() { return { // 搜索结果列表 searchList:[] } }
-
在防抖的
setTimeout
中,调用getSearchList
方法获取搜索建议列表: -
在
methods
中定义getSearchList
方法如下:(调用接口要用异步函数)
4 渲染搜索建议列表
-
定义如下的 UI 结构:
<!-- 搜索建议列表 --> <view class="sugg-list"> <view class="sugg-item" v-for="(item, i) in searchResults" :key="i" @click="gotoDetail(item.goods_id)"> <view class="goods-name">{{item.goods_name}}</view> <uni-icons type="arrowright" size="16"></uni-icons> </view> </view>
-
美化搜索建议列表
-
点击搜索建议的 Item 项,跳转到商品详情页面:
gotoDetail(goods_id) { uni.navigateTo({ // 指定详情页面的 URL 地址,并传递 goods_id 参数 url: '/subpkg/goods_detail/goods_detail?goods_id=' + goods_id }) }
搜索历史
1 渲染搜索历史记录的基本结构
-
在 data 中定义搜索历史的
假数据
:data() { return { // 搜索关键词的历史记录 historyList: ['a', 'app', 'apple'] } }
-
渲染搜索历史区域的 UI 结构:
-
美化搜索历史区域的样式:
2 实现搜索建议和搜索历史的按需展示
-
当搜索结果列表的长度
不为 0
的时候(searchResults.length !== 0
),需要展示搜索建议区域,隐藏搜索历史区域 -
当搜索结果列表的长度
等于 0
的时候(searchResults.length === 0
),需要隐藏搜索建议区域,展示搜索历史区域 -
使用
v-if
和v-else
控制这两个区域的显示和隐藏,示例代码如下:<!-- 搜索建议列表 --> <view class="sugg-list" v-if="searchResults.length !== 0"> <!-- 省略其它代码... --> </view> <!-- 搜索历史 --> <view class="history-box" v-else> <!-- 省略其它代码... --> </view>
3 将搜索关键词存入 historyList
-
直接将搜索关键词
push
到historyList
数组中即可methods: { // 根据搜索关键词,搜索商品建议列表 async getSearchList() { // 省略其它不必要的代码... // 1. 查询到搜索建议之后,调用 saveSearchHistory() 方法保存搜索关键词 this.saveSearchHistory() }, // 2. 保存搜索关键词的方法 saveSearchHistory() { // 2.1 直接把搜索关键词 push 到 historyList 数组中 this.historyList.push(this.kw) } }
-
上述实现思路存在的问题:
- 关键词前后顺序的问题(可以调用数组的
reverse() 方法
对数组进行反转) - 关键词重复的问题(可以使用 Set 对象进行去重操作)
- 关键词前后顺序的问题(可以调用数组的
4 解决关键字前后顺序的问题(最新搜索记录在前)
-
data 中的
historyList
不做任何修改,依然使用 push 进行末尾追加 -
定义一个计算属性
historys
,将historyList
数组reverse
反转之后,就是此计算属性的值:computed: { historys() { // 注意:由于数组是引用类型,所以不要直接基于原数组调用 reverse 方法,以免修改原数组中元素的顺序 // 而是应该新建一个内存无关的数组,再进行 reverse 反转 return [...this.historyList].reverse() } }
-
页面中渲染搜索关键词的时候,不再使用 data 中的
historyList
,而是使用计算属性historys
:<view class="history-list"> <uni-tag :text="item" v-for="(item, i) in historys" :key="i"></uni-tag> </view>
5 解决关键词重复的问题
-
修改
saveSearchHistory
方法如下:// 保存搜索关键词为历史记录 saveSearchHistory() { // this.historyList.push(this.kw) // 1. 将 Array 数组转化为 Set 对象 const set = new Set(this.historyList) // 2. 调用 Set 对象的 delete 方法,移除对应的元素 set.delete(this.kw) // 3. 调用 Set 对象的 add 方法,向 Set 中添加元素 set.add(this.kw) // 4. 将 Set 对象转化为 Array 数组 this.historyList = Array.from(set) }
6 将搜索历史记录持久化存储到本地
-
修改
saveSearchHistory
方法如下:
-
在
onLoad
生命周期函数中,加载本地存储的搜索历史记录:onLoad() { this.historyList = JSON.parse(uni.getStorageSync('kw') || '[]') }
7 清空搜索历史记录
-
为清空的图标按钮绑定
click
事件:<uni-icons type="trash" size="17" @click="cleanHistory"></uni-icons>
-
在
methods
中定义cleanHistory
处理函数:// 清空搜索历史记录 cleanHistory() { // 清空 data 中保存的搜索历史 this.historyList = [] // 清空本地存储中记录的搜索历史 uni.setStorageSync('kw', '[]') }
8 点击搜索历史跳转到商品列表页面
-
为搜索历史的 Item 项绑定
click
事件处理函数:<uni-tag :text="item" v-for="(item, i) in historys" :key="i" @click="gotoGoodsList(item)"></uni-tag>
-
在
methods
中定义gotoGoodsList
处理函数:// 点击跳转到商品列表页面 gotoGoodsList(kw) { uni.navigateTo({ url: '/subpkg/goods_list/goods_list?query=' + kw }) }
-
- 开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17天,点击查看活动详情