关于移动端UI框架 Vant 的van-tab和van-list的问题以及解决方案。

海星吧 2021-5-8 5945

这几天在做移动端的东西,然后就遇上了个问题。

vant这个框架我不是很熟悉,所以在开始用的时候没有注意它的问题。

结果昨天写一个根据不同状态查询列表的组件,出现了加载两次相同数据的bug。

不过也是前端请求的问题我就没找后台的麻烦(毕竟自己拉的屎,屁股自己擦)

van-list这个组件的onload函数是根据dom和可视区底部的距离来触发的,

immediate-check这个属性是在组件初始化的时候进行检查距离,但这个不是问题所在。

我切换tab的时候如果list被拉到了底部,那么它在进入下一个tab的同时,会进行两次相同的请求。

讲道理我开始真的很纳闷,我以为tab切换会把dom也给换掉,但我看了下F12,

list不是嵌套在tab里面的,也就是说切换tab只是改变了数据,并没有切换list这个dom。

也就是说在这个时候dom和可视区底部的距离突然变成了可触发的状态,

但因为请求是异步的,所以在数据没有渲染之前又触发了一次。

于是我还是仔细看了下list这个组件触发onload的方式。

发现它v-model绑定的是否加载的状态其实是可以阻挡onload的触发的。

然后我就在切换tab的触发函数里先把list的v-model绑定的loading给设置成true(list会在onload之前自动把loading改为true)

这个时候就没有同时请求两次的bug了。

(其实说了这么多我还是没搞懂van-list的细节,还是技术太菜了,表达能力低等。)

下面放出我的代码供有需要的兄弟参考。(欢迎补充和指导。)

<template>
	<div class="myOrder">
		<van-tabs v-model="tabAlive" @click="tabClick" sticky>
			<van-tab v-for="tab in tabList" :key="tab.id" :title="tab.text">
				<van-list 
				    v-model="loading" 
				    offset="20" 
				    :finished="finished" 
				    finished-text="没有更多了..." 
				    @load="onLoad">
					<div class="order" v-for="(item, index) in tableData" :title="item">
					    {{ index }}
					</div>
				</van-list>
			</van-tab>
		</van-tabs>
	</div>
</template>
<script>
import ApiCourseOrder from '@/api/courseOrder.js';
export default {
	data() {
		return {
			tabAlive: 0,
			tabList: [
				{ id: 0, text: '全部', payStatus: undefined },
				{ id: 1, text: '待付款', payStatus: 0 },
				{ id: 2, text: '待收货', payStatus: 1 },
				{ id: 3, text: '已完成', payStatus: 2 },
				{ id: 4, text: '已取消', payStatus: -1 }
			],
			loading: false,
			finished: false,
			tableData: [],
			total: 0,
			tableQueryOption: {
				pageNo: 1,
				pageSize: 5,
				payStatus: undefined
			}
		};
	},
	created() {
		if (this.$route.params.payStatus) {
			for (let i in this.tabList) {
				if (this.$route.params.payStatus == this.tabList[i].payStatus) {
				    //进入页面时初始化请求类型
					this.tabAlive = Number(i)
					this.tableQueryOption.payStatus = this.$route.params.payStatus;
				}
			}
		}
	},
	methods: {
		async onLoad() {
			// this.loading = true
			let data = await this.getCourseOrder();
			this.tableData.push(...data);
			if (!!!data||data.length < this.tableQueryOption.pageSize) {
				this.finished = true;
				return ;
			}
			return;
			console.log(data);
		},
		async tabClick(index, title) {
			this.loading = true;//如果滚动条到达底部,切换tab时会提交两次请求。所以先设置成true表示正在加载。
			this.finished = false;
			// 初始化请求状态
			this.tableQueryOption.payStatus = this.tabList[index].payStatus;
			this.tableQueryOption.pageNo = 1;
			this.tableData = [];
			//准备完成后触发onload函数
			this.onLoad()
		},
		async getCourseOrder() {
		        //获取数据的函数
			let params = {
				...this.tableQueryOption
			};
			console.log(params);
			let { data, total } = await ApiCourseOrder.getCourseOrderList(params);
			this.total = total;
			this.loading = false;
			this.tableQueryOption.pageNo += 1;
			return data;
		}
	}
};
</script>






弱鸡程序员年底还在加班
最新回复 (1)
  • 海星吧 2021-5-8
    0 2
    喀秋莎 这个代码能出H情节吗?
    上次的H情节已经让欧派兽拒绝与我的所有互动了
    弱鸡程序员年底还在加班
    • ACG里世界
      3
          
返回
发新帖