首页 > 其他分享 >uniapp实现虚拟列表(元素固定高度)

uniapp实现虚拟列表(元素固定高度)

时间:2024-04-12 22:23:45浏览次数:31  
标签:uniapp listData 列表 item startIndex 虚拟 scrollTop Math

一、应用场景

当接口返回数据太多时,前端可使用虚拟列表,实现长列表。

二、原理

只有在屏幕部分元素被显示出来,并且被更新,始终只有固定数量的节点,不会卡顿。

三、效果图
虚拟列表效果图

四、思路步骤

  • 使用 Object.freeze 冻结对象,极大优化性能
  • 生成多个元素的options, 或者动态获取
  • 根据onPageScroll生命周期监听页面滚动,得到scrollTop, 就是滚动条滑块的位置距离顶部的高度
  • startIndex为显示数组索引最小值, startIndex与 scrollTop 对应关系:
    this.startIndex = Math.floor(scrollTop / this.ceilHeight);
  • 滚动的时候修改显示的列表,屏幕显示列表为
    this.listData.slice(this.startIndex, Math.min(this.endIndex, this.listData.length))

五、代码

点击查看代码
<template>

	<!-- 长列表 -->
	<view class="list_box" :style="{height:`${listData.length * ceilHeight}px`}">
		<!--可视区列表  -->
		<!-- transform: `translateY(${offsetDistance}px)` -->
		<ul class="list1" ref="list_box" :style="{height: `${renderHeight}px`, top:`${offsetDistance}px` }">
			<li v-for="(item, index) in visibleData" :key="index" class="item">
				{{ item }}
			</li>
		</ul>
	</view>
</template>

<script>
	// 冻结对象 Object.freeze  因为vue的Object.defineProtory  数据劫持 导致数据是双向绑定的 所以需要使用冻结对象, 劫持侦听
	export default {

		data() {
			return {
				renderHeight: 0, //用户的视口高度
				ceilHeight: 50, //单行高度 rpx
				listData: [], //最全数据的列表
				// visibleData: [], //可视区显示的数据
				startIndex: 0, //起始位置
				endIndex: 0, //结束位置
				top: 0,
				// visibleCount: 0, //
				offsetDistance: 0, //偏移量

			}
		},
		onLoad() {

			let sysInfo = uni.getSystemInfoSync()
			this.renderHeight = sysInfo.windowHeight; //获取设备屏幕的高度

			this.listData = Array.from({
				length: 200000
			}).map((item, index) => this.getMockData(index))
		},
		mounted() {
			// 结束位置:起始位置+可视区显示的item 数量
			this.endIndex = this.startIndex + this.visibleCount
		},
		computed: {
			// 可视区显示的item 数量:设备屏幕高度/ 每个item的高度
			visibleCount() {
				// 向上取整
				let count = Math.ceil(this.renderHeight / this.ceilHeight)
				return count

			},
			visibleData() {
				// 返回最小的哪个数字 Math.min
				let list = this.listData.slice(this.startIndex, Math.min(this.endIndex, this.listData.length))
				return Object.freeze(list)
			},

		},
		// 监听页面滚动
		onPageScroll({
			scrollTop
		}) {
			// 计算起始位置:距离顶部高度/ 每个item的高度
			this.startIndex = Math.floor(scrollTop / this.ceilHeight);
			// 计算结束位置
			this.endIndex = this.startIndex + this.visibleCount
			//计算偏移量(防止闪烁跳跃) ↓
			this.offsetDistance = scrollTop - (scrollTop % this.ceilHeight);
		},
		methods: {
			getMockData(index) {
				return `index:${index} ${' **** '.repeat(2)}`
			}
		}
	}
</script>


<style>
	.list_box {
		position: relative;
	background-color: #ededed;
	}

	.list1 {
		position: absolute;

		left: 0;
		right: 0;

	}

	.item {
		height: 50px;
		line-height: 50px;
		border-bottom: 1px solid #ccc;
		text-align: left;
		list-style: none;
	}
</style>

六、补充
Object.freeze()冻结对象

  1. 一个大的数据对象里,在你确信它不需要改变的时候,你可以给他freeze(),可以大大的增加性能。
  2. 也可用作冻结线上的配置文件中的对象,以防有人误改。

标签:uniapp,listData,列表,item,startIndex,虚拟,scrollTop,Math
From: https://www.cnblogs.com/cat-eol/p/18132230

相关文章

  • 虚拟机Centos设置静态ip
    NAT模式相当于宿主机内部的一个虚拟网络,与宿主机公用一个IP.桥接相当于和宿主机平行,独立的IP和网卡.1设置开机自启#vi/etc/sysconfig/network-scripts/ifcfg-ens33将no改为yes#ONBOOT=yes#systemctlrestartnetwork#重启网络2下载网络工具如果有就不需要安装了......
  • uniapp做微信小程序遇到的一些问题汇总
    1.当我写完代码想手机预览的时候,小程序的启用组件按需注入显示未通过 加一句搞定//启用组件按需注入问题  "lazyCodeLoading":"requiredComponents", 2.微信开发者工具-右上角-详情-基本信息-代码依赖分析-可以看哪些文件比较大(如static下不超过200K,一般情况图片都......
  • otlp采集数据的虚拟机环境配置
    采集+监控1.LBLB配置文件,nginx自带的ngx_http_stub_status_module提供的/nginx_status(可自定义命名)端点输出的是nginx自己的简单状态信息vimInforSuiteLB/conf/InforSuiteLB.conflocation/nginx_status{stub_statuson;#access_logoff;......
  • 针对列表中的字典去重
    背景:我有一个列表,列表中存储的子元素是字典,字典中存在多个键值对,其中id是绝对不相同的,但其他键值对可能和另外的子元素重复,现在要去除重复的子元素#原始列表original_list=[{"id":1,"name":"Alice","age":20},{"id":2,"name":"Bob","age&q......
  • vmware虚拟机安装CentOS 7.9
    为.net6在CentOS7上面做准备,先在vmware虚拟机安装CentOS7.9新建CentOS764位的系统因为CentOS8不更新了,所以安装7;简单就一笔带过了  选择下载好的操作系统的iso文件,下载地址https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/?spm=a2c6h.25603864.0.0.1f90f5adDfcZ......
  • “AI虚拟数字人+线下大屏互动”升级智能人机交互服务!
    如今AIGC强势爆发、ChatGPT语言大模型横空出世,使得数字人的“大脑”水平得到了极大提升,AI技术赋能下的虚拟数字人拥有了更加精准的语言表达、思考逻辑。帮助各个行业实现了智能化、数字化升级,有效提升行业竞争力。目前,交互数字人显示的主要载体是PC、手机、智慧大屏、银行VTM机......
  • vmware安装macos提示客户机操作系统已禁用 CPU。请关闭或重置虚拟机
    客户机操作系统已禁用CPU。请关闭或重置虚拟机。这是AMD电脑的VMware安装macOS出现的错误我们需要在虚拟机运行之前打开虚拟机安装目录自动生成的macOSxxxx(你选择安装的版本号).vmx只需要在末尾添加:smc.version="0"cpuid.0.eax="0000:0000:0000:0000:0000:0000:0000:......
  • VMware虚拟机迁移到PVE
    VMware虚拟机迁移到PVEpve7.4https://blog.csdn.net/o12345612345666885/article/details/129679746从vmware导出虚拟机,导出为ovf上传ovf文件和vmdk磁盘到PVE后台(不要修改vmdk磁盘名称)根据ovf文件和vmdk磁盘创建虚拟机qmimportovf102centos7.ovfsatasdb--formatqco......
  • 虚拟机-Linux开发板交叉编译问题记录
    遇到一堆很久之前见过的问题,重新解决一次。1、虚拟机没法上网发现虚拟机浏览器上不了网,运行ifconfig查看,发现要么没有IP地址,要么只有IPv6的地址。最后发现是昨天VMware卡死了,启动任务管理器把相关任务全停了,dhcp服务没启动。于是点进计算机-管理-服务,重新启动。再把网络设置成NA......
  • 虚拟机windows7创建共享文件夹
    我们在桌面新建一个文件夹,最好重命名成英文或者数字的名称,我这里命名为“fix”。接下来,右键文件夹-属性-共享-高级共享-勾选“共享此文件夹”。开启共享此文件夹点击,权限-勾选允许完全控制-应用-确定-应用-确定-确定。给予读写权限接着我们查看虚拟机的IPv4地址,虚拟机的网络连......