目录
  • 1、问题描述
    • 原因分析
  • 2、先了解一下相关知识点
    • 1)基础用法
    • 2)List 的运行机制是什么?
    • 3)为什么 List 初始化后会立即触发 load 事件?
    • 4)为什么会连续触发 load 事件?
    • 5)loading 和 finished 分别是什么含义?
  • 3、代码
    • 总结

      1、问题描述

      3个tab页签切换时,调用不同接口,在某一个tab只要翻页到>=2的情况,当它再点击到另一个tab的时候,另外一个tab就会连续调用两次查询接口,有可能第二次查询的数据先于第一次查询返回,这时两次数据concat后顺序就不对了(第二次查到的数据在前,第一次在后)

      原因分析

      因为它不仅触发了created还触发了onload事件:且顺序为:进入created调用查询接口,在.then之前,异步查询还未返回的时候,又会去触发onload事件,在current+=1之后再次进行查询

      2、先了解一下相关知识点

      1)基础用法

      List 组件通过 loading 和 finished 两个变量控制加载状态,当组件滚动到底部时,会触发 load事件并将 loading 设置成 true。

      此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。

      若数据已全部加载完毕,则直接将 finished 设置成 true 即可。

      2)List 的运行机制是什么?

      List 会监听浏览器的滚动事件并计算列表的位置,当列表底部与可视区域的距离小于offset时,List会触发一次 load 事件。

      3)为什么 List 初始化后会立即触发 load 事件?

      List 初始化后会触发一次 load事件,用于加载第一屏的数据,这个特性可以通过immediate-check属性关闭。

      4)为什么会连续触发 load 事件?

      如果一次请求加载的数据条数较少,导致列表内容无法铺满当前屏幕,List 会继续触发 load事件,直到内容铺满屏幕或数据全部加载完成。

      因此你需要调整每次获取的数据条数,理想情况下每次请求获取的数据条数应能够填满一屏高度。

      5)loading 和 finished 分别是什么含义?

      List有以下三种状态,理解这些状态有助于你正确地使用List组件:

      • 非加载中,loading为false,此时会根据列表滚动位置判断是否触发onload事件(列表内容不足一屏幕时,会直接触发)
      • 加载中,loading为true,表示正在发送异步请求,此时不会触发onload事件
      • 加载完成,finished为true,此时不会触发onload事件 在每次请求完毕后,需要手动将loading设置为false,表示加载结束

      这次遇到的问题,可以利用第五点,解决方法:

      在进入created的发送请求之前,将this.loading = true , ⇒⇒⇒ (利用:加载中,loading为true,表示正在发送异步请求,此时不会触发load事件),让系统知道此时正在异步请求数据,让它别触发onload事件

      3、代码

      <van-list
        v-model="loading" class="van-list-style" :immediate-check="false"
        :finished="finished" :finished-text="finishedText"
        :error.sync="error" error-text="请求失败,点击重新加载"
        @load="onLoad">
        <div class="list" v-if="dataList.length > 0">
          <div class="list-box2" v-for="(item,index) in dataList" :key="index" @click="handleClick(item)">
            ………………………………………
          </div>
        </div>
        <div v-if="noData" style="margin-top:30%">
          <img src="https://www.freexyz.cn/dev/@/common/imgs/no-data.png" alt="" style="width:100%">
        </div>
      </van-list>
       
      data() {
         return {
           dataList:[],
           current:1,
           size:10,
           loading: false, // 上拉加载 ?????? 
           finished: false, // 上拉加载完毕
           error: false, // 是否展示错误
           finishedText:"没有更多了",
           noData:false, // 是否展示没有数据的图片
           // offset: 100 // 滚动条与底部距离小于 offset 时触发load事件
         }
       },
       
       created() {
         // 调用列表查询接口
         this.init(this.tab)
       },
       
      methods:{
       init(val) {
         if(val === '1') {
           this.createList(1,10)
         } 
       },
         
      //查询接口
      createList(current,size) {
        let param = { current:current, size:size }
        
        // 重点!!!!!!!!!在这里将loading置为true
        this.loading = true;
       
        createList(param).then(res=>{
          let that = this
          if(res.status == true) {
         	 //赋值
            const dataList = res.body.records
            const pages = res.body.pages
            // 如果返回数据为空
            if(dataList == null || dataList.length === 0) {
              that.finished = true
              that.finishedText = "没发现任何东西,去其他地方逛逛吧~"
              that.noData = true
              return
            }
            // 加载状态结束  可以写在这里也可以写在finally里面
            that.loading = false;
            
            // 根据当前页进行数据处理
            if(that.current === 1) {
              that.dataList = dataList
            } else {
              that.dataList = that.dataList.concat(dataList)
            }
       
            // xxx!!!最后一页不足10条的情况 ,这样写实际有问题,因为如果是最后一页为10条的情况,就会第二次去调用接口
            //if(dataList.length < that.size) {
             // that.finished = true
             //that.finishedText = '没有更多了';
            //}
       
            // 使用这种!! 证明已经是最后一页了
            if(that.current === pages) {
              that.finished = true
              that.finishedText = '没有更多了';
            }
          }
        })
        .catch(err=>{this.error = true; })
        .finally(()=>{this.loading = false })
      },
       
      // 上拉刷新
       onLoad() {
         this.current+=1
         this.createList(this.current,this.size)
       },
      }

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。