07_案例二-本地生活列表页面

继续上一案例,完成点击九宫格内的对应功能,跳转到对应的详情列表页

效果图

要实现的功能:

  • 页面导航并传参
  • 上拉触底时加载下一页数据
  • 下拉刷新列表数据

页面导航并传参

完成这一步,首先要构建一个详情列表页,将首页的九宫格组件改造成跳转标签,跳转时携带参数

在app.json文件中的pages块,添加一个"pages/shopList/shopList"

  "pages":[
    "pages/home/home",
    "pages/message/message",
    "pages/contact/contact",
    "pages/shopList/shopList"
  ],

改造首页九宫格子组件的结构,将<view>改造成<navigator>组件,并给其添加url属性

<!-- 九宫格区域 -->
<view class="grid-list">
  <navigator class="grid-item" wx:for="{{gridList}}" wx:key="id" url="/pages/shopList/shopList?id={{item.id}}&title={{item.name}}">
    <image src="{{item.icon}}"></image>
    <text>{{item.name}}</text>
  </navigator>
</view>

改造完成后,可以看到首页页面展示并无变化,点击美食,就跳转到shopList页面,并且参数也传递过去了。

设置页面标题

点击微信开发文档,查看截图标识部分

九宫格每个详情页虽然设计是一样的,但是标题以及要展示的内容是不一样的,我们需要在跳转到对应的详情页时,动态修改页面标题,就要使用wx.setNavigationBarTitle(Object object)方法,这个方法应该在哪里被调用?肯定是要刚一进入页面的时候调用。

请查看这里

一个页面周期函数有五个,其中onLoad是页面数据加载的时候会调用,而onReady则是页面初次渲染完成后才会调用,我们要设置页面标题,肯定是要在数据渲染完成时才去设置的。

还记得我们前面怎么动态修改页面内容吗?在js文件的data块中定义数据,然后在页面中使用,当data中的数据被修改时,页面展示会动态变化,这里为什么不是如此做?而是直接调用一个方法?因为页面标题不是我们书写的,而是系统自带的,我们没有标题数据变量,不能直接修改,只能调用wx暴露出来的修改标题接口。

  onReady: function () {

  },

这个onReady方法没有参数,我们想要获取标题数据,只能在onLoad方法中将页面跳转时携带的参数保存在data块中,因为onLoad方法是在onReady方法之前被系统调用。

读者可能会问,这还不是要用到data块吗?在这里我们只是用data块来间接获取页面标题数据,一旦页面渲染完成,我们再通过dataSet方法修改data中的数据,也没办法改变标题,这跟之前的动态修改页面数据是有本质区别的。

修改shopList.js文件

// 暂存页面跳转的传参
  data: {
    query: {}
  },

// 将页面跳转的参数存储到data.query中
  onLoad: function (options) {
    this.setData({ query: options })
  },

//修改页面标题
  onReady: function () {
    wx.setNavigationBarTitle({
      title: this.data.query.title,
    })
  },

效果

之前一直是本地生活,现在成了美食,点击九宫格其他组件,同样会产生对应的改变

商铺列表页展示:

获取并渲染商铺列表数据

列表页面API接口

以分页的形式,加载指定分类下商铺列表的数据:

  1. 接口地址
  1. 请求方式
  • GET 请求
  1. 请求参数
  • _page 表示请求第几页的数据
  • _limit 表示每页请求几条数据

我们先请求数据并且测试一下。

在shopList页面的data块定义几个变量用来存放相关数据

  data: {
    query: {},    // 存放页面跳转时携带的参数
    shopList:[],  // 存放商铺列表数据
    page:1,       // 默认是从第1页开始
    pageSize:10,  // 默认是每页10条数据
    total:0       // 数据总条数
  },

定义方法getShopList,获取商铺列表数据,在onLoad方法中调用,完成页面加载时的数据请求

  getShopList() {
    wx.request({
      url: `https://www.escook.cn/categories/${this.data.query.id}/shops`,
      method: 'get',
      data: {
        _page: this.data.page,
        _limit: this.data.pageSize
      },
      success: (res) => {
        // 将数据保存到data中
        this.setData({
          shopList: [...this.data.shopList, ...res.data],
          total: res.header['X-Total-Count'] - 0
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({ query: options })
    this.getShopList() //调用商铺列表数据请求方法
  },

编译测试

数据请求成功

渲染数据

// wxml 部分
<view class="shop-item" wx:for="{{shopList}}" wx:key="{{id}}">
  <view class="thumb">
    <image src="{{item.images[0]}}"></image>
  </view>
  <view class="info">
    <text class="shop-title">{{item.name}}</text>
    <text>电话:{{item.phone}}</text>
    <text>地址:{{item.address}}</text>
    <text>营业时间:{{item.businessHours}}</text>
  </view>
</view>

// wxss部分
.shop-item {
  display: flex;
  padding: 15rpx;
  border: 1rpx solid #efefef;
  margin: 15rpx;
  border-radius: 15rpx;
  box-shadow: 1rpx 1rpx 15rpx #ddd;
}

.thumb image {
  width: 250rpx;
  height: 250rpx;
  display: block;
  margin-right: 15rpx;
}

.info {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  font-size: 24rpx;
}

.shop-title {
  font-weight: bold;
}

展示效果

添加loading效果,修改getShopList方法

  getShopList() {
    //展示loading
    wx.showLoading({
      title: '数据加载中',
    })
    wx.request({
      url: `https://www.escook.cn/categories/${this.data.query.id}/shops`,
      method: 'get',
      data: {
        _page: this.data.page,
        _limit: this.data.pageSize
      },
      success: (res) => {
        // 将数据保存到data中
        this.setData({
          shopList: [...this.data.shopList, ...res.data],
          total: res.header['X-Total-Count'] - 0
        })
      },
      complete: () => {
        // loading隐藏
        wx.hideLoading()
      }
    })
  },

配置上拉触底加载下一页数据效果

配置上拉触底,修改shoplist.json文件

{
  "usingComponents": {},
  "onReachBottomDistance": 200 //改为上拉触底200像素触发
}

修改shoplist.js文件,在onReachBottom中监听触底事件

  onReachBottom: function () {
    console.log('ok');
  },

编译,测试

修改onReachBottom

  onReachBottom: function () {
    this.setData({
      page: this.data.page + 1
    })
    this.getShopList()
  },

可以看到页面内容确实增加了,并且当前页标识page字段也在增加

给上拉事件做节流处理。因为在网速偏慢的情况下,当前页没有请求并且加载完,是不应该请求下一次的数据。

请求节流的方法,在data块中配置一个节流阀 isLoading,默认值为false,每次请求方法getShopList代码一开始执行就要先将节流阀置为true。如果不管请求成功还是失败,都将该节流阀置为false。而在上拉触底监听方法中,每次调用getShopList之前应该判断当前是否在请求数据,如果在请求数据,应该直接返回,本次不执行。

具体代码如下

// 设置节流阀
  data: {
    query: {},    // 存放页面跳转时携带的参数
    shopList: [],  // 存放商铺列表数据
    page: 1,       // 默认是从第1页开始
    pageSize: 10,  // 默认是每页10条数据
    total: 0,      // 数据总条数
    isLoading: false // 节流阀
  },

// 控制节流阀
  getShopList() {
    // 打开节流阀
    this.setData({ isLoading: true })
    //展示loading
    wx.showLoading({
      title: '数据加载中',
    })
    wx.request({
      url: `https://www.escook.cn/categories/${this.data.query.id}/shops`,
      method: 'get',
      data: {
        _page: this.data.page,
        _limit: this.data.pageSize
      },
      success: (res) => {
        // 将数据保存到data中
        this.setData({
          shopList: [...this.data.shopList, ...res.data],
          total: res.header['X-Total-Count'] - 0
        })
      },
      complete: () => {
        // loading隐藏
        wx.hideLoading()
        // 关闭节流阀
        this.setData({ isLoading: false })
      }
    })
  },

// 判断节流阀
  onReachBottom: function () {
    // 判断节流阀
    if (this.data.isLoading) return
    this.setData({
      page: this.data.page + 1
    })
    this.getShopList()
  },

这个不太好演示,截图也不能展示出来,读者请自行验证

判断数据是否加载完毕

后台数据是有限的,本次案例美食下只有80条数据,每次请求10条,那我们肯定不能请求第九次,第十次吧

如果下面的公式成立,则证明没有下一页数据了

页码值 * 每页数据条数 >= 数据总条数
page * pageSize >= total

修改 onReachBottom 方法,加入数据是否加载完毕的操作

  onReachBottom: function () {
    if (this.data.page * this.data.pageSize >= this.data.total) {
      return wx.showToast({
        title: '数据加载完毕',
        icon: 'none'
      })
    }
    // 判断节流阀
    if (this.data.isLoading) return
    this.setData({
      page: this.data.page + 1
    })
    this.getShopList()
  },

效果

开启页面下拉刷新操作

修改shopList的json配置文件

{
  "usingComponents": {},
  "onReachBottomDistance": 200,
  "enablePullDownRefresh": true,//开启下拉刷新
  "backgroundColor": "#efefef", //修改下拉刷新的背景色
  "backgroundTextStyle": "dark" //给下拉刷新添加小圆点
}

下拉刷新效果确实添加了

我们还需要在js文件中修改下拉刷新的样式,值得注意的是,在手机上调试会发现,下拉刷新不会自动关闭,下拉刷新操作需要我们手动关闭。同时我们希望下拉刷新之后重新请求数据,即,当前页码值为1。

主要修改这几处地方

onPullDownRefresh: function () {
  this.setData({
    page: 1, //重置页码值
    shopList: [], //清空列表数据
    total: 0//总数居条数清空
  })

  // 重新发起请求,并且传入一个回调函数
  this.getShopList(()=>{wx.stopPullDownRefresh()})
},

// ------------------------------------------------------------

getShopList(cb) {//给一个cb参数,用来判断当前是否需要关闭下拉刷新
  // 打开节流阀
  this.setData({ isLoading: true })
  //展示loading
  wx.showLoading({
    title: '数据加载中',
  })
  wx.request({
    url: `https://www.escook.cn/categories/${this.data.query.id}/shops`,
    method: 'get',
    data: {
      _page: this.data.page,
      _limit: this.data.pageSize
    },
    success: (res) => {
      // 将数据保存到data中
      this.setData({
        shopList: [...this.data.shopList, ...res.data],
        total: res.header['X-Total-Count'] - 0
      })
    },
    complete: () => {
      // loading隐藏
      wx.hideLoading()
      // 关闭节流阀
      this.setData({ isLoading: false })
      // 关闭下拉刷新操作,因为很多地方都会调用这个请求函数,但不是所有的请求数据场景下都需要关闭下来刷新操作,只有在下拉刷新时才需要调用
      cb && cb()
    }
  })
},

真机测试不好截图,读者请自行验证

posted @   yaowy  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示