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

56 篇文章 4 订阅

目录

List 列表

Toast 轻提示

解决方案

1、不使用 Toast 的 加载提示

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

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

4、forbidClick 设置为 false

5、自定义组件


背景 :

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

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 的 加载提示。

项目实际使用 :

<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 { getStData } 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 getStData(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>

时隔多日,开发移动端项目时,此问题再次引发,需要进一步深入排查解除一下,

1、经排查发现 Toast.loading({ forbidClick: true }) 可以禁用背景点击,

但同样会导致 van-list 组件滚动高度出现问题

2、得出结论:由于 全局拦截器 加载中 Toast.loading({ forbidClick: true }) 导致

forbidClick是否禁止背景点击booleanfalse

4、forbidClick 设置为 false

Toast.loading({ forbidClick: false }) 将 forbidClick 设置为 false 可解决该问题,

但同样会导致背景可点击。


5、自定义组件

模拟 Toast 组件效果即可

<template>
  <van-popup v-model="appLoading" :close-on-click-overlay="false" :overlay="false">
    <div class="loading-wrap">
      <van-loading color="#fff" />
    </div>
  </van-popup>
</template>

<script>
import { Popup, Loading } from 'vant'

export default {
  components: {
    [Popup.name]: Popup,
    [Loading.name]: Loading
  },
  props: {
    appLoading: {
      type: Boolean,
      default: false
    }
  }
}
</script>

<style lang="scss" scoped>
.van-popup {
  background-color: transparent;
  border-radius: 12px;
  overflow: hidden;
}

.loading-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 130px;
  height: 130px;
  background-color: rgba(0, 0, 0, 0.7);
}
</style>
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值