vant-list组件触发多次onload事件导致数据乱序的解决方案

 更新时间:2023年01月20日 08:49:06   作者:huangzhin  
这篇文章主要介绍了vant-list组件触发多次onload事件导致数据乱序的解决方案

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="@/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)
 },
}

总结

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

相关文章

  • Vue3中使用匿名函数的方法实现

    Vue3中使用匿名函数的方法实现

    Lambda函数,也称为匿名函数,是Vue3中的一种函数类型,绑定匿名方法和绑定普通方法主要是写法上的区别,其他的区别并不是很大,本文主要介绍了Vue3中使用匿名函数的方法实现,感兴趣的可以了解一下
    2023-12-12
  • 实例讲解Vue.js中router传参

    实例讲解Vue.js中router传参

    本篇文章通过实例给大家分析了Vue.js中router传参的相关知识点,对此有兴趣的朋友参考学习下。
    2018-04-04
  • VUE html5-qrcode实现H5扫一扫功能实例

    VUE html5-qrcode实现H5扫一扫功能实例

    这篇文章主要给大家介绍了关于VUE html5-qrcode实现H5扫一扫功能的相关资料,html5-qrcode是轻量级和跨平台的QR码和条形码扫码的JS库,集成二维码、条形码和其他一些类型的代码扫描功能,需要的朋友可以参考下
    2023-08-08
  • vue之将echart封装为组件

    vue之将echart封装为组件

    这篇文章主要介绍了vue之将echart封装为组件,本文将会以雷达图为案例,一步步讲解在vue项目中如何使用echart,如何将其封装为能重复调用的组件
    2018-06-06
  • Vue中引入echarts的步骤及折线图、柱状图常见配置项

    Vue中引入echarts的步骤及折线图、柱状图常见配置项

    这篇文章主要介绍了Vue中引入echarts的步骤及折线图、柱状图常见配置项,需要的朋友可以参考下
    2023-11-11
  • vue部署包可配置后台接口地址的方法

    vue部署包可配置后台接口地址的方法

    这篇文章主要介绍了vue部署包可配置后台接口地址的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Vue手动控制点击事件Click触发方式

    Vue手动控制点击事件Click触发方式

    这篇文章主要介绍了Vue手动控制点击事件Click触发方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • vue2.0 + ele的循环表单及验证字段方法

    vue2.0 + ele的循环表单及验证字段方法

    今天小编就为大家分享一篇vue2.0 + ele的循环表单及验证字段方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue实现大文件分片上传与断点续传到七牛云

    vue实现大文件分片上传与断点续传到七牛云

    这篇文章介绍了vue实现大文件分片上传与断点续传到七牛云的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 详解Vue源码学习之callHook钩子函数

    详解Vue源码学习之callHook钩子函数

    这篇文章主要介绍了详解Vue源码学习之callHook钩子函数,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07

最新评论