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

虚拟列表在微信小程序下不生效,数量800条时会崩溃 #175

Open
icjking opened this issue Dec 5, 2024 · 6 comments
Open

Comments

@icjking
Copy link

icjking commented Dec 5, 2024

编译平台
webstorm

VUE版本
vue3中出现的问题,框架基于uniapp
vue版本:3.4.21
ui: [email protected]
vite: 5.4.11

运行平台
微信小程序

z-paging版本
2.8.4

问题描述
请详细描述问题,最好说明复现步骤,尽可能附上代码或截图
virtual-list-demo.vue代码如下:

<!-- 虚拟列表演示(不使用内置列表)(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"
			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 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">虚拟列表展示</text>
					<view class="item-detail">{{ item.detail }}</view>
				</view>
				<view class="item-line"></view>
			</view>
		</z-paging>
	</view>
</template>

<script lang="ts" setup>
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue';

interface QueryParams {
	pageNo: number;
	pageSize: number;
	type: number;
}

// 定义类型
interface ListItem {
	id?: string | number;
	title: string;
	detail: string;
	// 额外的属性
	zp_index: number;
}

const paging = ref(null);

const tabIndex = ref(0);
const tabList = ref(['cell高度相同', 'cell高度不同']);
// 虚拟列表数组,通过@virtualListChange监听获取最新数组
const virtualList = ref<ListItem[]>([]);

const tabsChange = (index) => {
	tabIndex.value = index;
	// 当切换tab或搜索时请调用组件的reload方法,请勿直接调用:queryList方法!!
	paging.value.reload();
};

// 监听虚拟列表数组改变并赋值给virtualList进行重新渲染
const virtualListChange = (vList) => {
	virtualList.value = vList;
};

// @query所绑定的方法不要自己调用!!需要刷新列表数据时,只需要调用paging.value.reload()即可
const queryList = async (pageNo, pageSize) => {
	// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
	// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
	// 模拟请求服务器获取分页数据,请替换成自己的网络请求
	try {
		const params: QueryParams = {
			pageNo,
			pageSize,
			type: tabIndex.value + 1,
		};

		// 模拟网络请求
		const res: any = await mockRequest(params);
		paging.value?.complete(res.data.list);
	} catch (error) {
		console.error('请求失败:', error);
		paging.value?.complete(false);
		// 可以使用统一的错误处理
		// uni.$emit('z-paging-error-emit')
	}
};

// 列表项点击
const itemClick = (item: ListItem, zIndex: number) => {
	console.log('点击了', item.title, zIndex);
	uni.showToast({
		title: `点击了${item.title}`,
		icon: 'none',
	});
};

// 模拟网络请求
const mockRequest = (params: QueryParams) => {
	return new Promise((resolve) => {
		setTimeout(() => {
			const list = Array(params.pageSize)
				.fill(0)
				.map((_, index) => ({
					id: `${params.pageNo}-${index}`,
					title: `第${params.pageNo}-${index}行标题`,
					detail: `详情${params.pageNo}-${index}`,
				}));
			resolve({
				data: {
					list,
					total: 100,
				},
			});
		}, 500);
	});
};
</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 0;
	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: 0;
	left: 0;
	height: 1px;
	width: 100%;
	background-color: #eeeeee;
}
</style>

编译后小程序有两个问题:
1、cell高度相同(默认列表),上拉加载数据未增加
2、cell高度不同,上拉加载正常,加载多次后,查看dom数量,是累计增加的,和 描述不符
image

image
@SmileZXLee
Copy link
Owner

demo也会这样吗,试了下是正常的

@icjking
Copy link
Author

icjking commented Dec 6, 2024

直接跑示例也是哦,地址:https://github.com/SmileZXLee/uni-z-paging/tree/main/demo/z-paging-vue3-demo
这个我下载了,用HBuilderX打开,运行到微信小程序,然后真机调试(ios),选择虚拟列表演示(非内置列表写法),选择cell高度不同,然后滚动几次,回到微信开发者工具,查看dom结构,会发现没有销毁

@SmileZXLee
Copy link
Owner

image 试了下,94条之前的已经被销毁

@icjking
Copy link
Author

icjking commented Dec 6, 2024

image 确实,我这53条前也是销毁了,但是这个示例放入我的框架里,就没销毁(框架是用的unibest),我查查问题,感谢

@SmileZXLee
Copy link
Owner

好的,不客气

@SmileZXLee
Copy link
Owner

image
此外试了一下在微信小程序中使用虚拟列表5000+条依然流畅,理论上1万+条也没有问题(主要是手刷酸了才到5000条)

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

No branches or pull requests

2 participants