likes
comments
collection
share

Weapp影视评分项目开发(16):搜索页的实现(下)swiper 结合 scroll-view 实现滑动 tab 页

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

前言

本篇是搜索页实现的下篇,主要讲解如何使用 swiper 结合 scroll-view 标签实现 tab 页的滑动切换效果。

知识点

swiper 结合 scroll-view 实现 tab 页滑动切换

一、功能介绍

因为搜索结果有影视、影人、角色三种类型,目前微信小程序的 swiper 中嵌套 scroll-view 的效果还不错,兼容层面的 bug 基本解决了,所以我对原来的点击 tab 切换的效果做了升级,现在内容可滑动切换的方式,以带来更好的用户体验。

二、 效果预览

Weapp影视评分项目开发(16):搜索页的实现(下)swiper 结合 scroll-view 实现滑动 tab 页

三、效果实现

1. 页面布局

页面布局部分之前有提到过,搜索结果对应的组件为 search-result,我们要做的是把内容部分占满。

需要注意的是, swiperscroll-view 组件都需要设置高度,否则两个都会使用默认值,且 swiper 的高度不会被内容(这里的内容是 scroll-view 标签)自动撑满。

布局主要代码如下:

<view class="result-list">
  <!-- swiper 组件,我们需要监听它的 change 值的改变,使上方菜单与其对应 -->
  <!-- swiper 需要设置高度把页面撑满,因为上方高度为 166rpx,所以此处高度为 calc(100vh - 166rpx) -->
  <swiper class="swiper" bindchange="handleSwiper" current="{{current}}">
    <!-- 此处的 swiper-item 可以使用 wx:for 循环处理,为方便理解,未使用 -->
    <swiper-item>
      <!-- 滚动标签的使用,设置为 y 轴滚动 -->
      <!-- 我们需要监听滚动触底事件,以加载更多内容 -->
      <scroll-view class="scroll-view" scroll-y bindscrolltolower="handleReachBottom">
        <movie-item wx:for="{{movies}}" movie="{{item}}" wx:key="id" />
      </scroll-view>
    </swiper-item>
    <!-- 影人 -->
    <swiper-item>
      <scroll-view class="scroll-view" scroll-y bindscrolltolower="handleReachBottom">
        <actor-item wx:for="{{actors}}" actor="{{item}}" wx:key="id" />
      </scroll-view>
    </swiper-item>
    <!-- 角色代码略 -->
  </swiper>
</view>

注意: 以上代码中,swiper-item 标签可以使用 wx:for 循环来处理,为便于理解,此处直接写了两个 swiper-item 标签。为简化代码,角色部分代码、加载动画、触底提示、无数据提示等内容移除了,可以按需要在每个内容区域增加对应的代码。

样式代码:

.result-list {
  padding-top: 74rpx;
  .swiper, .scroll-view  {
    /* 不设置高度不会被内容撑开 */
    /* 高度需要设置为屏幕剩余区域高度 */
    height: calc(100vh - 166rpx);
  }
}

2. 逻辑交互

上一篇我们讲了查询接口请求相关的实现,本篇关于接口查询部分的代码就不再赘述,主要讲一下 swiper 切换与 tab 直接是如何显示对应的,以及变更后的数据结构信息。

1) 如何初始化数据结构

因为查询有三种类型,所以我们将其定义为了一个数组对象,这样既方便模板渲染时直接使用循环展示内容,又方便数据初始化设置,即使后期需要添加其它类型,也只需要在类型数组中增加相应属性即可。

data: {
  current: 0, // swiper 当前索引
  tabList: [] // 默认类型数组
},
attached() {
  this.initData();  // 进入时初始化类型数据结构
},
methods: {
  initData() {
    // 类型默认数据
    const tabList = [
      {
        name: "影视",      // tab 显示的名称
        type: "movie",     // type 类型,接口查询时使用
        loading: false,    // 该类型是否在查询状态,用于显示查询加载动画
        page: 1,           // 当前结果页码
        list: [],          // 当前查询影视列表
        noMoreData: false, // 数据是否显示完
        total: 0,          // 查询结果条数
      }
      // 为简化代码,影人、角色信息初始化方式被移除
    ];
    
    this.setData({
      tabList     // 初始化数据结构
    })
  }
}

当变更查询关键字时,我们需要重置数据结构为默认值,这时就可以调用以上的 initData 方法:

watch: {
  keyword(val) {
    if (val) {
      this.refreshSearch();  // 有查询关键字变更
    }
  }
},
// 重置数据结构并发起接口查询
refreshSearch() {
  this.initData();
  this.doSearch();
}
2) swiper 事件与 tab 切换关联

上面的模板中,我们监听了 swiperbindchange 事件,该事件会返回一个 current 值,为当前 swiper-item 的索引值,我们可以根据该值来设置对应的 tab 值:

// swiper 切换时改变对应类型
handleSwiper({ detail }) {
  const current = e.detail
  const type = this.data.tabList[current].type; // 获取当前类型
  this.typeChange(type);
},

// 类型切换时改变对应 swiper 索引
typeChange(e) {
  // 当 tab 切换时,我们需要取消上次接口请求,
  // 否则上次类型的请求结果会放入本次类型的结果中
  if (this.data.cancel) {
    this.data.cancel.abort();
    this.data.cancel = null;
  }
  // tab 切换有两种情况,第一种是点击上方的 tab 类型
  // 否则是由 handleSwiper 方法中传入 type 值进行调用
  const type = e.currentTarget ? e.currentTarget.dataset.type : e;
  const current = this.data.tabList.findIndex(t => t.type === type); // 当前类型对应索引
  this.setData({
    current  // tab 类型切换需要改变 swiper 显示为对应项
  })
}
3) 查询结果设置

因为类型是一个数组,所以我们接口查询出对应数据时,需要做对应数组的内容改变,这时我们可以使用以下方法:

const {code, data, total } = response; // 接口返回结果伪代码

const index = this.data.tabList.findIndex(t => t.type === this.data.type);
const tab = this.data.tabList[index];

// 以下方式设置要变更的 key 值
const list_key = 'tabList[' + index + '].list';
const page_key = 'tabList[' + index + '].page';
const total_key = 'tabList[' + index + '].total';

this.setData({
  [list_key]: tab.list.concat(data), // 合并新增数据
  [page_key]: ++tab.page,
  [total_key]: total
})

最后

本篇我们已经将搜索页面的主要内容介绍完毕,它是日常业务中常用到的一个页面,一般情况下业务不会比这个复杂,其中最重要的是网络请求取消方法的使用。 下一篇,我们将开始讲解项目中最复杂的一个页面——影视详情页的实现。

转载自:https://juejin.cn/post/7176661503720816697
评论
请登录