目录
背景 :
移动端项目?开发时,有数据长列表展示的场景需求,此时就用到了
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
<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,以便下次触发加载 } else { // 没有更多数据了(需停止继续加载) this.loading = false; this.finished = true; // 数据全部加载完成(true) } }, }, }; </script>