这几天在做移动端的东西,然后就遇上了个问题。
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>