Weapp影视评分项目开发(14):搜索页的实现(上)页面布局与组件拆分
前言
本篇我们将开始讲解搜索页的实现,由于内容较多,将会分为上中下三篇来讲述。
- 上篇:页面布局与组件拆分,搜索框组件的实现
- 中篇:防抖与 wx.request 请求取消
- 下篇:tab 页面处理,搜索结果缓存
知识点
页面布局
组件拆分
搜索框实现
样式穿透
一、搜索页预览


二、功能介绍
搜索页面的入口是首页顶部的搜索框,点击后就可进入搜索页,搜索框默认为 focus
属性,会打开系统软键盘,用户可直接输入查询条件,搜索采用关键字模糊搜索,使用防抖功能限制用户输入的频率,持续输入时,会取消之前关键字触发的请求。
查询功能提供了三种分类:影视、影人与角色,切换后会发起对应类型的请求,将查询结果在对应的 tab 下显示出来。结果列表支持滚动分页。
三、页面布局介绍
由上面的预览图可以看出,搜索页由上中下三部分组成:
- 上方:搜索框,滚动时固定在顶部
- 中间:类型切换菜单,无搜索关键字时不显示,滚动时固定在顶部
- 下方:无搜索关键字时展示历史记录(如果有历史记录),有搜索关键字时显示搜索结果列表,列表支持滚动
四、组件拆分与布局的实现
右上方的布局可知,我们可以将该页面拆分为四个组件,即:搜索框、类型切换菜单、搜索结果与历史记录。其结构如下:
├── search // 搜索页面
│ ├── components // 搜索组件
│ │ ├── search-bar // 顶部搜索框
│ │ ├── search-tabs // 类型菜单
│ │ ├── search-result // 搜索结果
│ │ └── search-history // 搜索历史
│ └── index.xxx // 页面文件
1. search-bar 组件的实现
1. index.wxml
介绍
search-bar
组件主要是一个 input
输入框,其核心模板代码如下:
<input class="search__input"
confirm-type="search"
type="text"
value="{{value}}"
focus
bindinput="keywordChange"
bindconfirm="doSearch"
placeholder="找影视 / 影人 / 角色"
/>
其相关属性说明如下:
confirm-type="search"
:系统软键盘右下角的按钮文字会显示为 “搜索”;value
:当用户点击搜索历史时给其赋值;focus
:使输入框获取焦点,进入时就会显示软键盘,减少用户操作;bindinput
:用户输入监听,用于触发模糊搜索;bindconfirm
:点击右下角“搜索”按钮时,用于触发搜索;
2. index.scss
介绍
样式部分没有复杂的功能,主要是需要将搜索框 fixed
定位在顶部,不随页面滚动。
3. index.js
介绍
js
部分也没有需要特别复杂的地方,主要是需要将用户输入的关键字与触发的事件,传递给父组件,即父子传值 properties
与子父传值 triggerEvent
的使用:
Component({
properties: {
// 输入框文字
value: {
type: String,
value: ""
},
},
methods: {
// 用户输入时会持续触发 input 事件,我们需要将 `keyword` 传递给父组件
keywordChange({ detail }) {
this.triggerEvent("keyword-change", detail.value);
},
// 用户点击了软键盘右下角搜索按钮
doSearch({ detail }) {
this.triggerEvent("keyword-change", detail.value);
},
// 清空输入的关键字
clearValue() {
this.triggerEvent("on-clear");
},
// 取消按钮,返回上一页,即首页
cancel() {
wx.navigateBack();
}
}
})
2. search-tabs
布局的实现
1. index.wxml
介绍
模板的实现并不复杂,就是三个菜单的元素横向排列即可:
<view class="menu-list menu-{{type}}">
<view
class="menu-item {{type === 'movie' ? 'is-active': ''}}"
data-type="movie"
bindtap="typeChange"
>影视</view>
<!-- 影人与角色与上面基本相同,略 -->
</view>
2. index.scss
介绍
类型菜单也是需要固定在顶部,不随页面滚动,其重点在于切换时下方跟随的主题色横线的实现,它是使用了 css
伪元素 ::after
,配合 transform
的 translateX
进行 x 轴的位置偏移实现:
.menu-list {
z-index: 9;
position: fixed; /* 绝对定位 */
left: 0;
right: 0;
top: 80rpx;
padding-left: 12rpx;
height: 84rpx;
// 伪元素实现底部随动线条
&::after {
content: "";
position: absolute;
left: 68rpx;
bottom: 4rpx;
width: 46rpx;
height: 6rpx;
background-color: var(--color-theme);
border-radius: 4rpx;
transform: translateX(-50%); /* x轴偏移 */
transition: left 0.2s; /* 过度动画,使平移顺滑 */
}
}
3. search-result 布局的实现
1. index.wxml
介绍
该组件模板用于展示搜索结果列表,未脱离文档流,主要是根据上方类型的切换,结果列表也进行相应的展示内容切换即可,所以代码就不做展示了。
1. index.scss
介绍
样式主要有以下两点需要注意:
- 设置
padding-top
值,该空间被上面的两个组件fixed
定位所占用; - 改写
movie-item
等几个组件的样式,主要是调整大小,以使页面能展示更多的搜索结果,所以需要给movie-item
组件开启样式穿透styleIsolation: 'apply-shared'
,允许父组件修改其样式。
.result-list {
padding: 80rpx 0 15rpx;
}
4. search-history 布局的实现
search-history
组件的布局过于简单,在此就不做过多赘述,主要提一下清空历史记录时的弹窗组件,该弹窗需要在 wxml
中添加 <m-modal id="modal" />
模板,虽然清空的事件是在 search-history
中,但是该模板必须写在 page
页面中。
最后
本篇文章并未过多涉及到搜索页的业务逻辑部分,主要讲解了布局的实现与组件的拆分,可能内容较为简单,但良好的布局,才能为后面的业务逻辑实现带来便捷。组件的拆分,虽然会增加组件间的沟通成本,但与功能的清晰划分与可维护性的提高相比还是值得的。 下一篇,我们将使用防抖与 wx.request 请求取消,来实现搜索结果的展示。
转载自:https://juejin.cn/post/7175549960400666684