Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更新v-model绑定的数据,内部$nextTick回调函数没有调用 #185

Open
c-sopoo opened this issue Jan 22, 2025 · 2 comments
Open
Labels
question Further information is requested

Comments

@c-sopoo
Copy link

c-sopoo commented Jan 22, 2025

** 请描述您在使用期间遇到的疑问 **
hbuilderX:4.45,微信小程序

我的业务场景:使用虚拟列表滚动分页,需要从接口轮询更新排序
具体操作:v-model绑定数据,通过轮询,修改了v-model绑定的数据后,看源码会触发updateVirtualListRender方法,但内部的nextTick回调没有被调用,是uni-app的bug?理应是每次都会被调用的吧

初步猜测是uni-app的bug,

简单实现,修改示例代码virtual-list-no-inner-demo.vue

Image
添加如下方法:

update() {
	setTimeout(() => {
		console.log('更新了')
		this.totalData = [...this.totalData]
		this.update()
	}, 5000)
}

简单调用:

Image
添加日志:

Image

微信小程序实际表现:😦???nextTick回调怎么没有被调用

Image

H5表现:

Image

@c-sopoo c-sopoo added the question Further information is requested label Jan 22, 2025
@SmileZXLee
Copy link
Owner

我试了vue2和3,运行z-paging的demo到微信小程序,updateVirtualListRender和nextTick均有触发。HBuilderX版本4.45,微信小程序开发者工具版本Stable 1.06.2409140

Image

Image

@c-sopoo
Copy link
Author

c-sopoo commented Feb 14, 2025

看看我的完整示例,不要滚动页面,就只轮询;
微信小程序(Nightly 1.06.2502112)中,update方法中如果不调用this.$refs.paging.updateVirtualListRender(),日志nextTick不打印,页面数据不会更新;
h5上不调用this.$refs.paging.updateVirtualListRender()也会更新;

<!-- 虚拟列表演示(不使用内置列表)(vue) -->
<!-- 写法较简单,在页面中对当前需要渲染的虚拟列表数据进行for循环,在vue3中兼容性良好 -->
<!-- 在各平台兼容性请查阅https://z-paging.zxlee.cn/module/virtual-list.html -->
<template>
	<view class="content">
		<!-- 如果页面中的cell高度是固定不变的,则不需要设置cell-height-mode,如果页面中高度是动态改变的,则设置cell-height-mode="dynamic" -->
		<!-- 原先的v-model修改为@virtualListChange="virtualListChange"并赋值处理后的虚拟列表 -->
		<z-paging ref="paging" v-model="totalData" use-virtual-list :force-close-inner-list="true" :cell-height-mode="tabIndex===0?'fixed':'dynamic'" @virtualListChange="virtualListChange" @query="queryList">
			<!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
			<template #top>
				<view class="header">列表总数据量:10万条</view>
				<!-- 注意!此处的z-tabs为独立的组件,可替换为第三方的tabs,若需要使用z-tabs,请在插件市场搜索z-tabs并引入,否则会报插件找不到的错误 -->
				<z-tabs :list="tabList" @change="tabsChange" />
			</template>
			
			<!-- :id="`zp-id-${item.zp_index}`"和:key="item.zp_index" 必须写,必须写!!!! -->
			<!-- 这里for循环的index不是数组中真实的index了,请使用item.zp_index获取真实的index -->
			<view class="item" :id="`zp-id-${item.zp_index}`" :key="item.zp_index" v-for="(item,index) in virtualList" @click="itemClick(item,item.zp_index)">
				<image class="item-image" mode="aspectFit" src="@/static/boji1.png"></image>
				<view class="item-content">
					<text class="item-title">第{{item.title}}行</text>
					<text style="color: red;margin-left: 10rpx;">虚拟列表展示{{ item.__t }}</text>
					<view class="item-detail">{{item.detail}}</view>
				</view>
				<view class="item-line"></view>
			</view>
		</z-paging>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// 虚拟列表数组,通过@virtualListChange监听获得最新数组
				virtualList: [],
				tabList: ['cell高度相同','cell高度不同'],
				tabIndex: 0,
				totalData: []
			}
		},
		methods: {
			tabsChange(index) {
				this.tabIndex = index;
				// 当切换tab或搜索时请调用组件的reload方法,请勿直接调用:queryList方法!!
				this.$refs.paging.reload();
			},
			// 监听虚拟列表数组改变并赋值给virtualList进行重新渲染
			virtualListChange(vList) {
				this.virtualList = vList;
			},
			queryList(pageNo, pageSize) {
				// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
				// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
				// 模拟请求服务器获取分页数据,请替换成自己的网络请求
				const params = {
					pageNo: pageNo,
					pageSize: pageSize,
					random: this.tabIndex === 1
				}
				this.$request.queryListLong(params).then(res => {
					// 将请求的结果数组传递给z-paging
					this.$refs.paging.complete(res.data.list);
					this.update()
				}).catch(res => {
					// 如果请求失败写this.$refs.paging.complete(false);
					// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
					// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
					this.$refs.paging.complete(false);
				})
			},
			itemClick(item, index) {
				console.log('点击了', item.title);
			},
			update() {
				setTimeout(() => {
					const len = this.totalData.length
					const i = Math.floor(Math.random() * len)
					console.log('更新了', i)
					this.totalData[i] = {
						...this.totalData[i],
						__t: new Date().toLocaleString()
					}
					this.totalData = [...this.totalData]
					this.update()
					// this.$nextTick(() => {
					// 	this.$refs.paging.updateVirtualListRender()
					// })
				}, 5000)
			}
		}
	}
</script>

<style>
	.item {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 20rpx 30rpx;
	}
	
	.item-content{
		flex: 1;
		margin-left: 20rpx;
	}
	
	.header{
		background-color: red;
		font-size: 24rpx;
		text-align: center;
		padding: 20rpx 0rpx;
		color: white;
	}
	
	.item-image{
		height: 150rpx;
		width: 150rpx;
		background-color: #eeeeee;
		border-radius: 10rpx;
	}
	
	.item-title{
		background-color: red;
		color: white;
		font-size: 26rpx;
		border-radius: 5rpx;
		padding: 5rpx 10rpx;
	}
	
	.item-detail {
		margin-top: 10rpx;
		border-radius: 10rpx;
		font-size: 28rpx;
		color: #aaaaaa;
		word-break: break-all;
	}

	.item-line {
		position: absolute;
		bottom: 0rpx;
		left: 0rpx;
		height: 1px;
		width: 100%;
		background-color: #eeeeee;
	}
</style>

20250214_093605.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants