vant List组件实现上拉加载中 首次进行load事件执行两次的问题

需求:
进行tab切换时,其中一次tab下有上拉加载的功能

问题:
在第一次切换到带有上拉加载列表功能的tab,执行加载list的load事件执行了两次造成数据的重复加载,另外如果这个list的高度全部在可视范围内,首次就会加载两次load事件,如果可视范围只有tab切换的区域则不会出现这种情况

如图所示,tab3下的是具有上拉加载功能的list
在这里插入图片描述

解决:
方法一:分开load绑定的事件和第一次加载数据执行事件,并添加:immediate-check=“false”,禁止在初始化时立即执行滚动位置检查。
代码:
注:只添加:immediate-check="false"这个项目中不太好使,还是可能会首次执行两回。

<van-list v-if="firstTabIndex==2" v-model="loading" :finished="finished" finished-text="没有更多啦" offset="10" 
	:immediate-check="false" @load="onLoad">
	<ul class="hotel2-info-ul">
		<li class="hotel2-info-li" v-for="item in dataList" :key="`jx${item.id}`">
			<div class="area">
				<van-icon name="location" /><span class="city-name">名称</span>
			</div>
			<div class="hotel-name"><span>描述{{ item.id }}</span></div>
		</li>
	</ul>
</van-list>

js代码:

export default {
	name: "flight-pay-status",
	data() {
		return {
			dataInfo: {},//调用需要的相关数据
			dataList: [],// 数据
			firstTabIndex: 3,// 一级菜单下标
			secondTabIndex: 0,// 二级菜单下标
			secondTabList: [],// 二级菜单列表
			jxParams: {  //查询信息
				start: 0,
				limit: 10,
				cityCode: ''
			},
			loading: false,
			finished: false,
			refreshing: false,
		};
	},
	methods: {
		// 一级菜单切换
		firstTab(index){
			let initIndex = this.firstTabIndex;
			this.firstTabIndex = index;
			this.dataList = [];
			if(index==0){
				this.getFirstData();
			}else if(index==1){
				this.getSecondData();
			}else if(index==2){
				this.jxParams.start = 0;
				this.dataList = [];
				this.getLoadData();
			}else if(index==3){
				this.getFourData();
			}
		},
		// 切换获取数据
		getLoadData(){
			let para = {
				start: this.jxParams.start,
				limit: this.jxParams.limit,
				otherType: 2,
				cityCode: this.dataInfo.arrivalCityHotelCode
			}
			this.loading = true;
			myAPI.searchAround(para).then(res => {
				if(res.status){
					this.loading = false;
					let datas = res.data.hotels;
					this.dataList = datas;
					this.finished = res.data.total === this.dataList.length;
					this.jxParams.start = 1;
					this.loading = false;
					console.log(this.dataList);
				}else{
					this.tools.tip(res.data);
				}
			})
		},
		//上拉加载
		async onLoad(){
			let para = {
				start: this.jxParams.start,
				limit: this.jxParams.limit,
				otherType: 2,
				cityCode: this.dataInfo.arrivalCityHotelCode
			}
			this.loading = true;
			myAPI.searchAround(para).then(res => {
				if(res.status){
					let datas = res.data.hotels;
					this.dataList = this.dataList.concat(datas);
					if(this.dataList.length < res.data.total){
						this.jxParams.start++;
						this.loading = false;
					}else{
						this.finished = true;
						this.loading = true;
					}
				}else{
					this.tools.tip(res.data);
				}
			})
		},
	}
}

方法二:
这个也可能是样式问题造成的,绿色块儿是异步加载,里面的当图片没到onload事件时候,没渲染出来,宽高都为0。vant 的触底事件判断又在渲染之前。就会瞬间判断没填满当前空间,就会立刻又加载一次。
鉴于此,给这个绿色块儿添加最小高度。

<think>好的,用户想了解在Vue3中使用VantList组件的使用方法、示例和属性。首先,我需要回忆一下Vant的文档内容,特别是Vue3版本的部分。记得VantList组件通常用于长列表的渲染,并且支持上拉加载更多数据,结合PullRefresh组件还能实现下拉刷新功能。 用户提供的引用内容中有提到List组件和PullRefresh组件的结合使用,所以在回答中需要包括这两个组件的配合示例。同时要注意引用标识的正确添加,比如在提到下拉刷新和上拉加载的时候,需要引用对应的引用源。 接下来,我需要整理List组件的基本用法,包括安装Vant、引入List组件,然后在模板中使用<van-list>标签。属性方面,v-model:loading、finished、immediate-check、offset这些都是常用的,需要解释清楚每个属性的作用。 示例代码部分,用户可能需要一个完整的Vue3组件示例,包括数据加载的逻辑,比如onLoad函数如何处理分页,如何更新列表数据,以及如何标记加载完成。同时,结合PullRefresh的话,要展示如何嵌套使用这两个组件,处理下拉刷新时重置数据的情况。 另外,需要注意用户可能遇到的常见问题,比如多次调用接口的问题。引用3中提到UI组件---vantList组件接口多次调用大坑问题,这可能是因为没有正确管理加载状态,或者在滚动时频繁触发load事件。这时候需要提醒用户检查offset属性的设置,或者使用immediate-check来防止初始化时立即加载。 最后,生成相关问题的时候,要考虑用户可能进一步想知道的内容,比如如何与PullRefresh结合、常见错误处理以及属性优化等。这样可以帮助用户更全面地应用List组件。</think>### Vue3 Vant List 组件使用指南 #### 一、基础用法 Vant List 组件用于长列表渲染,支持**上拉加载更多**功能。结合 `van-pull-refresh` 可实现下拉刷新[^1]。 ```html <template> <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad" > <van-cell v-for="item in list" :key="item" :title="item" /> </van-list> </template> <script setup> import { ref } from 'vue'; const list = ref([]); const loading = ref(false); const finished = ref(false); const onLoad = () => { setTimeout(() => { for (let i = 0; i < 10; i++) { list.value.push(list.value.length + 1); } loading.value = false; if (list.value.length >= 40) { finished.value = true; } }, 1000); }; </script> ``` #### 二、核心属性说明 | 属性 | 类型 | 说明 | |------|------|------| | `v-model:loading` | Boolean | 控制加载状态(自动绑定) | | `finished` | Boolean | 是否已加载全部数据 | | `immediate-check` | Boolean | 是否初始化时立即检查滚动位置(默认true)[^3] | | `offset` | Number | 触发加载的滚动距离阈值(建议50-100)[^3] | #### 三、结合下拉刷新 ```html <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> <van-list v-model:loading="loading" :finished="finished" @load="onLoad" > <!-- 列表内容 --> </van-list> </van-pull-refresh> ``` 需同步管理刷新状态: ```javascript const refreshing = ref(false); const onRefresh = () => { list.value = []; // 清空数据 finished.value = false; onLoad(); // 重新加载 refreshing.value = false; }; ``` #### 四、注意事项 1. **接口多次调用问题**:设置 `offset="50"` 可避免滚动到底部前多次触发[^3] 2. **自动检查机制**:初始化时设置 `immediate-check="false"` 防止自动加载 3. **数据重置逻辑**:下拉刷新时要清空数据并重置 `finished` 状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值