likes
comments
collection
share

Weapp影视评分项目开发(14):搜索页的实现(上)页面布局与组件拆分

作者站长头像
站长
· 阅读数 14

前言

本篇我们将开始讲解搜索页的实现,由于内容较多,将会分为上中下三篇来讲述。

  • 上篇:页面布局与组件拆分,搜索框组件的实现
  • 中篇:防抖与 wx.request 请求取消
  • 下篇:tab 页面处理,搜索结果缓存

知识点

页面布局 组件拆分 搜索框实现 样式穿透

一、搜索页预览

Weapp影视评分项目开发(14):搜索页的实现(上)页面布局与组件拆分 Weapp影视评分项目开发(14):搜索页的实现(上)页面布局与组件拆分

二、功能介绍

搜索页面的入口是首页顶部的搜索框,点击后就可进入搜索页,搜索框默认为 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 ,配合 transformtranslateX 进行 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
评论
请登录