likes
comments
collection
share

小程序的下拉刷新和上拉加载

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

初步实现上拉加载更多

  1. 打开项目根目录中的 pages.json 配置文件,为 subPackages 分包中的 goods_list 页面配置上拉触底的距离:

     "subPackages": [
       {
         "root": "subpkg",
         "pages": [
           {
             "path": "goods_detail/goods_detail",
             "style": {}
           },
           {
             "path": "goods_list/goods_list",
             "style": {
               "onReachBottomDistance": 150
             }
           },
           {
             "path": "search/search",
             "style": {}
           }
         ]
       }
     ]
    
  2. 在 goods_list 页面中,和 methods 节点平级,声明 onReachBottom 事件处理函数,用来监听页面的上拉触底行为:

    // 触底的事件
    onReachBottom() {
      // 让页码值自增 +1
      this.queryObj.pagenum += 1
      // 重新获取列表数据
      this.getGoodsList()
    }
    
  3. 改造 methods 中的 getGoodsList 函数,当列表数据请求成功之后,进行新旧数据的拼接处理:

    // 获取商品列表数据的方法
    async getGoodsList() {
      // 发起请求
      const { data: res } = await uni.$http.get('/api/public/v1/goods/search', this.queryObj)
      if (res.meta.status !== 200) return uni.$showMsg()
    
      // 为数据赋值:通过展开运算符的形式,进行新旧数据的拼接
      this.goodsList = [...this.goodsList, ...res.message.goods]
      this.total = res.message.total
    }
    

通过节流阀防止发起额外的请求

  1. 在 data 中定义 isloading 节流阀如下:

    data() {
      return {
        // 是否正在请求数据
        isloading: false
      }
    }
    
  2. 修改 getGoodsList 方法,在请求数据前后,分别打开和关闭节流阀:

    // 获取商品列表数据的方法
    async getGoodsList() {
      // ** 打开节流阀
      this.isloading = true
      // 发起请求
      const { data: res } = await uni.$http.get('/api/public/v1/goods/search', this.queryObj)
      // ** 关闭节流阀
      this.isloading = false
    
      // 省略其它代码...
    }
    
  3. 在 onReachBottom 触底事件处理函数中,根据节流阀的状态,来决定是否发起请求:

    // 触底的事件
    onReachBottom() {
      // 判断是否正在请求其它数据,如果是,则不发起额外的请求
      if (this.isloading) return
    
      this.queryObj.pagenum += 1
      this.getGoodsList()
    }
    

判断数据是否加载完毕

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

    当前的页码值 * 每页显示多少条数据 >= 总数条数
    pagenum * pagesize >= total
    
  2. 修改 onReachBottom 事件处理函数如下:

    // 触底的事件
    onReachBottom() {
      // 判断是否还有下一页数据
      if (this.queryObj.pagenum * this.queryObj.pagesize >= this.total) return uni.$showMsg('数据加载完毕!')
    
      // 判断是否正在请求其它数据,如果是,则不发起额外的请求
      if (this.isloading) return
    
      this.queryObj.pagenum += 1
      this.getGoodsList()
    }
    

下拉刷新

  1. 在 pages.json 配置文件中,为当前的 goods_list 页面单独开启下拉刷新效果:

    "subPackages": [{
      "root": "subpkg",
      "pages": [{
        "path": "goods_detail/goods_detail",
        "style": {}
      }, {
        "path": "goods_list/goods_list",
        "style": {
          "onReachBottomDistance": 150,
          "enablePullDownRefresh": true,
          "backgroundColor": "#F8F8F8"
        }
      }, {
        "path": "search/search",
        "style": {}
      }]
    }]
    
  2. 监听页面的 onPullDownRefresh 事件处理函数:

    // 下拉刷新的事件
    onPullDownRefresh() {
      // 1. 重置关键数据
      this.queryObj.pagenum = 1
      this.total = 0
      this.isloading = false
      this.goodsList = []
    
      // 2. 重新发起请求
      this.getGoodsList(() => uni.stopPullDownRefresh())
    }
    
  3. 修改 getGoodsList 函数,接收 cb 回调函数并按需进行调用:

    // 获取商品列表数据的方法
    async getGoodsList(cb) {
      this.isloading = true
      const { data: res } = await uni.$http.get('/api/public/v1/goods/search', this.queryObj)
      this.isloading = false
      // 只要数据请求完毕,就立即按需调用 cb 回调函数
      cb && cb()
    
      if (res.meta.status !== 200) return uni.$showMsg()
      this.goodsList = [...this.goodsList, ...res.message.goods]
      this.total = res.message.total
    }
    
转载自:https://juejin.cn/post/7126154361108955172
评论
请登录