uniapp项目中的上拉触底事件

一、初步实现上拉触底

1.1 在项目中的 pages.json 文件找到自己要做 上拉触底事件的页面配置 onReachBottomDistance

{
  "path" : "goods_list/goods_list",
  "style" :                                                                                    
   {
     "navigationBarTitleText": "",
     "enablePullDownRefresh": false,
     "onReachBottomDistance": 150 // 上拉触底事件触发的距离
   }
}

1.2 在页面调用 上拉触底回调 onReachBottom

  onReachBottom() {
      // 每次触发上拉触底 请求的页码 自加一 
      this.queryObj.pagenum ++

      // 重新请求数据
      this.getGoodsList()
    }

1.3 在获取数据的函数中   获取到数据之后不要立即赋值,要将之前的数据与下拉触底获取到的数据合并

     async getGoodsList(){
        const {message:{total, goods}} = await api.getData("/goods/search", this.queryObj)
        // console.log(message)

        // 通过 ... 展开运算符 将 旧数据 与 上拉触底获取到的数据合并,重新存储起来
        this.goodsList = [...this.goodsList, ...goods]

        // 总共有多少条数据  后面会用到
        this.total = total
      }

二、 节流阀处理

2.1 在 data 中定义 节流阀

data() {
      return {
        isLoading: false // 节流阀 默认为关闭状态
      };
    },

 2.2 在进入发起请求的函数中  打开节流阀,请求发送出去之后 关闭节流阀,在上拉触底的函数中判断 节流阀为 true/false, 具体代码如下:

// 获取数据
async getGoodsList(){
        
        // 打开节流阀
        this.isLoading = true

        // 发送请求
        const {message:{total, goods}} = await api.getData("/goods/search", this.queryObj)
        // console.log(message)

        // 关闭节流阀
        this.isLoading = false
        this.goodsList = [...this.goodsList, ...goods]
        this.total = total
      }

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

三、判断数据是否请求完成,如果请求完成就不应该继续发起请求了

通过公式:(页码数 * 每一页获取数据的条数 >= 总条数)如果符合则说明已经没有数据了

3.1 在上拉触底事件中做判断

    onReachBottom() {
      // 判断数据是否全部请求完成
      if(this.queryObj.pagenum * this.queryObj.pagesize >= this.total) {
        return uni.showToast({
          title: "数据加载完毕!",
          duration: 1500,
          icon: "none"
        })
      }
      
      if(this.isLoading) return
      
      this.queryObj.pagenum ++
      this.getGoodsList()
    }

四、至此一个完整的上拉触底的关键代码就都写完了,以下是完整代码:

注意:不适合粘贴复制,只是怕大家看前面的关键代码段看的云里雾里,所以贴出完整代码以作对比

<template>
  <view>
    <view class="goods-list">
      <block v-for="(goods, i) in goodsList" :key="i">
        <my-goods :goods="goods"></my-goods>
      </block>
    </view>
  </view>
</template>

<script>
  import api from '@/api/index.js'
  export default {
    data() {
      return {
        queryObj:{
          query: '',
          cid: '',
          pagenum: 1, // 数据的页码
          pagesize: 10 // 每一页多少条数据 
        },
        goodsList: [],
        total: 0, // 总共多少条数据
        isLoading: false
      };
    },
    onLoad(option) {
      this.queryObj.query = option.query || ''
      this.queryObj.cid = option.cid || ''
      // console.log(this.queryObj)
      this.getGoodsList()
    },
    methods:{
// 请求数据的方法
      async getGoodsList(){
        this.isLoading = true
        const {message:{total, goods}} = await api.getData("/goods/search", this.queryObj)
        // console.log(message)
        this.isLoading = false
        this.goodsList = [...this.goodsList, ...goods]
        this.total = total
      }
    },
// 上拉触底事件
    onReachBottom() {
// 判断数据全部是否请求完成
      if(this.queryObj.pagenum * this.queryObj.pagesize >= this.total) {
        return uni.showToast({
          title: "数据加载完毕!",
          duration: 1500,
          icon: "none"
        })
      }
      
// 上条数据加载完毕再发起下一次请求
      if(this.isLoading) return
      
// 请求的页数
      this.queryObj.pagenum ++
      this.getGoodsList()
    }
  }
</script>

<style lang="scss">

</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值