Vant2组件库van-list+Toast下拉加载滚动条回顶问题

目录

[List 列表](#List 列表)

[Toast 轻提示](#Toast 轻提示)

解决方案

[1、不使用 Toast 的 加载提示](#1、不使用 Toast 的 加载提示)

[2、修改调整 pointer-event 属性值](#2、修改调整 pointer-event 属性值)

3、判断是否为第一次加载再使用


背景 :

移动端项目开发时,有数据长列表展示的场景需求,此时就用到了

Vant2 组件库里面的 <van-list> 列表组件,开始单独使用的时候还没有

下拉加载数据时滚动条会莫名自动返回到顶部的问题,知道后面为了提升用户的体验,

后续开发就结合加上了 Toast 轻提示组件,然后当时也并没有发现这个问题,

直到后续项目开发的差不多了,反复测试的过程中偶尔感受到了这里怎么这么奇怪,

为何下拉至底部加载新一页的数据时,滚动条又回到了顶部呢?开始并没有很在意,

以为本来就这样的,但经过百度一番后,才发现原来此处算是一个小 bug ,

而且现在回想感觉确实很影响用户体验了,所以接下来分享一下解决方案 :

可以看到,往下滚动加载第二页数据的时候,滚动条会滚动到顶部。正常应该是滚动条位置不变

List 列表

瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,

会触发事件并加载更多列表项。

Toast 轻提示

在页面中间弹出黑色半透明提示,用于消息通知、加载提示、操作结果提示等场景。

解决方案

1、不使用 Toast 的 加载提示

1-1、如果使用 异步加载数据 并使用了 Vant 中的 Toast 做加载中提示,

则有可能会导致列表滚动高度为 0 ,也就是回到了顶部。

只要在 list 加载回调里不使用 Toast 就可以避免这个问题。

1-2、因为每次 网络请求 ,使用了 Vant 的 Toast.loading 的加载中效果的 api,

如果去掉 Toast.loading 请求,则问题不会出现。


2、修改调整 pointer-event 属性值

主要原因是 Toast 组件在全局添加了 pointer-event: none

解决办法,在对应的 van-list 的属性值添加 pointer-event

( 未实际实验过此方法,所以不确保准确性,小伙伴们可自行判断使用 )


3、判断是否为第一次加载再使用

因为还想保留着初次进入列表页面时的 Toast 的 加载提示,

所以这里我们判断一下,是否为第一页(初次进入页面),

是的话则使用 Toast 的 加载提示。

项目实际使用 :

src / views / home / index.vue

javascript 复制代码
<template>
  <div>
    <van-list
      v-if="dataList.length > 0"
      v-model="loading"
      :finished="finished"
      finished-text="没有更多了"
      @load="onLoad"
    >
      <p>{{ 'ItemName' }}</p>
      <van-cell v-for="item in dataList" :key="item" :title="item" />
    </van-list>
    <div v-if="dataList.length === 0">
      <img src="" alt="空" />
      <p>暂无数据</p>
    </div>
  </div>
</template>

<script>
import { getStatisticsData } from '@api/index';

export default {
  data() {
    return {
      dataList: [], // 列表数据
      loading: false, // 加载显示与否
      finished: false, // 是否加载完毕
      formData: {
        surverId: '',
        currentPage: 1, // 当前页数
      },
    };
  },
  computed: {
    rqObj() {
      return this.$route.query || {};
    },
  },
  created() {
    if (this.rqObj.id && this.rqObj.id !== null) {
      this.formData.surveyId = this.rqObj.id;
      this.getDataList(this.formData);
    }
  },
  methods: {
    onLoad() {
      // 滚动到底部时触发
      this.formData.currentPage++;
      this.getDataList(this.formData);
    },
    async getDataList(data) {
      // 异步加载并使用Toast会导致列表滚动高度归零返回顶部
      // Toast.loading({
      //   message: '加载中...',
      //   forbidClick: true,
      //   duration: 0, // 持续展示 toast
      // });
      // 解决办法3:首次加载时使用提示,后续不再Toast提示
      if (this.formData.currentPage === 1) {
        Toast.loading({
          message: '加载中...',
          forbidClick: true,
          duration: 0, // 持续展示 toast
        });
      }
      // ==========================================
      let res = await getStatisticsData(data);
      const { code, result } = res;
      if (code === '0') {
        if (result.lists && result.lists.length > 0) {
          this.dataList = this.dataList.concat(result.lists);
        }
        // 加载状态结束
        this.loading = false;
        // 加载完成后需要将loading设置为false,以便下次触发加载
        Toast.clear()
      } else {
        // 没有更多数据了(需停止继续加载)
        this.loading = false;
        this.finished = true; // 数据全部加载完成(true)
      }
    },
  },
};
</script>
相关推荐
To_OC6 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic7 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy7 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志7 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble8 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯9 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜10 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司10 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g10 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森11 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http