前端虚拟滚动列表 vue虚拟列表

前端虚拟滚动列表

在大型的企业级项目中经常要渲染大量的数据,这种长列表是一个很普遍的场景,当列表内容越来越多就会导致页面滑动卡顿、白屏、数据渲染较慢的问题;大数据量列表性能优化,减少真实dom的渲染


看图:绿色是显示区域,绿色和蓝色中间属于预加载:解决滚动闪屏问题;大致了解了流程在往下看;
在这里插入图片描述

实现效果:

先说一下你看到这么多真实dom节点是因为做了预加载,减少滚动闪屏现象,这里写了300行,可以根据实际情况进行截取
在这里插入图片描述

实现思路:

虚拟列表滚动大致思路:两个div容器

  外层:外部容器用来固定列表容器的高度,同时生成滚动条内层:内部容器用来装元素,高度是所有元素高度的和外层容器鼠标滚动事件  dom.scrollTop 获取滚动条的位置根据每行列表的高以及当前滚动条的位置,利用slice() 去截取当前需要显示的内容重点:滚动条的高度是有内层容器的paddingBottom 和 paddingTop 属性顶起来了,确保滚动条位置的准确性这里鼠标上下滚动会出现闪屏问题:解决方案如下:方案一:  预加载:向下预加载:比如div滚动区域显示30行,就预加载 300行( 即这里 slice(startIndex,startIndex + 300) ),向上预加载:在滚动监听事件函数中(computeRow)判断inner的paddingTop和paddingBottom即可当然这里的download-box的padding有30px像素,在加一个div,overflow:hidded就解决了方案二:缩小滚动范围或者节流时间缩短,这里写的500ms

具体代码

  <template><div class="enn"><div class="download-box txt" id="scrollable-div" @scroll="handleScroll"><div id="inner"><div v-for="(item, index) in data2" :key="index" class="line-box"><div :class="{ 'text-box': props.collapsed, 'text-box-samll': !props.collapsed }">{{ item }}</div></div></div></div></div></template><script lang="ts" setup>import { onMounted, PropType, ref } from 'vue';import { useText } from './hooks/useText';const props = defineProps({baseData: {type: Object as PropType<{taskId: string;barcodeName: string;}>,default: {},},collapsed: {type: Boolean,default: true,},type: {type: Boolean,default: false,},});const { data } = useText(props.type);//  这里大数据量数组是  data.geneTexts/*** 虚拟列表滚动大致思路:两个div容器**    外层:外部容器用来固定列表容器的高度,同时生成滚动条**    内层:内部容器用来装元素,高度是所有元素高度的和**    外层容器鼠标滚动事件  dom.scrollTop 获取滚动条的位置**    根据每行列表的高以及当前滚动条的位置,利用slice() 去截取当前需要显示的内容**    重点:滚动条的高度是有内层容器的paddingBottom 和 paddingTop 属性顶起来了,确保滚动条位置的准确性**    这里鼠标上下滚动会出现闪屏问题:解决方案如下:**        方案一:  预加载:**                      向下预加载:*                          比如div滚动区域显示30行,就预加载 300行( 即这里 slice(startIndex,startIndex + 300) )**                      向上预加载:*                          在滚动监听事件函数中(computeRow)判断inner的paddingTop和paddingBottom即可**                      当然这里的download-box的padding有30px像素,在加一个div,overflow:hidded就解决了**        方案二:缩小滚动范围或者节流时间缩短,这里写的500ms***/let timer_throttle: any;const throttle = (func: Function, wait?: number) => {wait = wait || 500;if (!timer_throttle) {timer_throttle = setTimeout(() => {func.apply(this);timer_throttle = null;}, wait);}};// 鼠标滚动事件const handleScroll = (event: any) => throttle(computeRow, 100);// 计算当前显示tabconst computeRow = () => {// console.log('距离顶部距离', window.scrollY, geneTexts);let scrollableDiv = document.getElementById('scrollable-div');let topPosition = scrollableDiv.scrollTop;let leftPosition = scrollableDiv.scrollLeft;console.log('垂直滚动位置:', topPosition, '水平滚动位置:', leftPosition);const startIndex = Math.max(0, Math.floor(topPosition / 30));const endIndex = startIndex + 300;data2.value = data.geneTexts.slice(startIndex, endIndex);let inner = document.getElementById('inner');if (topPosition < 2700) {// 向上预计加载,这里判断了三个高度,可以多判断几个,增加流畅度inner.style.paddingTop = topPosition + 'px';inner.style.paddingBottom = (data.geneTexts.length + 2) * 30 - topPosition + 'px';} else if (topPosition + data2.value.length * 30 >= data.geneTexts.length * 30) {// 这里 9000 是 内层div的高度 30 * 300   理解div高度是 padding+div内容高度inner.style.paddingTop = topPosition - 900 + 'px'; //900 是div的高度inner.style.paddingBottom = 0 + 'px';} else {inner.style.paddingTop = topPosition - 2700 + 'px';inner.style.paddingBottom = (data.geneTexts.length + 2) * 30 + 2700 - topPosition + 'px';}};const data2 = ref([]);const init = () => {data2.value = data.geneTexts.slice(0, 300);let inner = document.getElementById('inner');inner.style.paddingTop = 0 + 'px';inner.style.paddingBottom = (data.geneTexts.length + 2) * 30 - 900 + 'px';};</script><style lang="less" scoped>.button-box {margin-bottom: 25px;.flex-type(flex-end);:deep(.ant-btn) {margin-left: 10px;}}.enn {background: #282c34;outline: 1px solid red;padding: 30px 20px;height: 960px;}.download-box {width: 100%;// padding: 30px 20px;outline: 1px solid rgb(17, 0, 255);background-color: #fff;overflow: hidden;.line-box {.flex-type(flex-start);height: 30px;}&.txt {background: #282c34;color: #fff;height: 900px;overflow: auto;}}</style>

替代方案

上面是自己写的,github上面还有好多插件可以用,但各有优劣,根据自己需求选择
如:

vue-virtual-scroller

https://github.com/Akryum/vue-virtual-scroller/tree/0f2e36248421ad69f41c9a08b8dcf7839527b8c2

vue-virt-list

vue-draggable-virtual-scroll-list

virtual-list

自己找吧,我就不一一列举了,看图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/783757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建 3D+虚拟人+ai 结合虚拟直播间

构建 3D 虚拟人与 AI 结合的虚拟直播间可以通过以下步骤实现&#xff1a; 1. 选择合适的平台和工具&#xff1a; 首先&#xff0c;你需要选择适合构建虚拟直播间的平台和工具。一些常用的平台包括 Unity、Unreal Engine 等&#xff0c;它们提供了强大的 3D 渲染和物理引擎&…

Qt之QSoundEffect播放简单音效

文章目录 前言一、为什么需要他二、QSoundEffect的使用2.1 简单使用2.2 QSoundEffect API2.3 槽函数2.4 信号总结前言 在开发Qt应用程序时,为用户提供音效可以增强用户体验,并且能够使应用程序更加生动和交互。Qt提供了QSoundEffect类,用于播放简单的音效,例如按键音、警告…

Prometheus +Grafana +node_exporter可视化监控Linux + windows虚机

1、介绍 背景&#xff1a;需要对多台虚机进行负载可视乎监控&#xff0c;并进行及时的报警 2、架构图 node_exporter &#xff1a;主要是负责采集服务器的信息。 Prometheus &#xff1a;主要是负责存储、抓取、聚合、查询方面。 Grafana &#xff1a; 主要是…

Pandas | value_counts() 的详细用法

value_counts() 函数得作用 用来统计数据表中&#xff0c;指定列里有多少个不同的数据值&#xff0c;并计算每个不同值有在该列中的个数&#xff0c;同时还能根据指定得参数返回排序后结果。 返回得是Series对象 value_counts(values,sortTrue, ascendingFalse, normalizeFal…

SSTI 服务器端模板注入(Server-Side Template Injection)

1.Web_python_template_injection {{}}是变量包裹标识符&#xff0c;里面存放的是一个变量&#xff0c;当你输入 http://61.147.171.105:55121/{{8*8}} 执行成功&#xff0c;说明存在模版注入。接下来&#xff0c;开始想办法编代码拿到服务器的控制台权限 。 首先&#xff0c…

unity 打包安卓错误汇集

Failed to find target with hash string "android-34’ in: D:Pr 他说找不到sdk34level的我用as打开后卸载又重装&#xff0c;最后解决了 我放到Plugins/Android/下面的Java代码没有被编译 这个不知道为什么。我故意把代码写的有问题&#xff0c;会报错那种&#xff…

Java中常见的锁策略

目录 乐观锁 vs 悲观锁 悲观锁: 乐观锁&#xff1a; 重量级锁 vs 轻量级锁 ⾃旋锁&#xff08;Spin Lock&#xff09; 公平锁 vs 非公平锁 可重⼊锁 vs 不可重入锁 读写锁 乐观锁 vs 悲观锁 悲观锁: 总是假设最坏的情况&#xff0c;每次去拿数据的时候都认为别…

一些常用的命令

onnx模型截断&#xff1a; onnx.utils.extract_model(onnx/mobilenet_v3_small_shape.onnx, onnx/mobilenet_v3_small_shape_truncated.onnx, [input.1], [262]) onnx.utils.extract_model(yolov7seg.onnx, yolov7seg_truncated.onnx, [images], [515, "625", &quo…

nginx 重启nginx脚本文件

原因 nginx 初期布置的时候&#xff0c;经常需要重启&#xff0c;手动的关闭重启nginx太麻烦&#xff0c;写一个重启脚本可以简化操作 文件 新建一个bat批处理文件&#xff0c;内容如下&#xff1a; 进入nginx所在文件夹重新读取配置退出杀死所有的nginx进程启动nginx显示nginx…

js教程(10)

一、日期对象 用来表示时间的对象&#xff0c;可以得到当前系统时间。 1.实例化 在代码中发现了new关键字时&#xff0c;一般将这个操作称为实例化&#xff0c;我们可以用new来创建一个时间对象并获取其值。 //创建当前时间对象 const dateNow new Date(); //创建指定时间对…

AES加密解密算法

一&#xff0c;AES算法概述 AES属于分组加密&#xff0c;算法明文长度固定为128位&#xff08;单位是比特bit&#xff0c;1bit就是1位&#xff0c;128位等于16字节&#xff09; 而密钥长度可以是128、192、256位 当密钥为128位时&#xff0c;需要循环10轮完成加密&#xff0…

Mysql中having和where的区别

having子句与where都是设定条件筛选的语句&#xff0c;有相似之处也有区别。 having与where的区别: having是在分组后对数据进行过滤 where是在分组前对数据进行过滤 having后面可以使用聚合函数 where后面不可以使用聚合 在查询过程中执行顺序&#xff1a;from>where>g…

http和https的区别!

HTTP 明文传输&#xff0c;数据都是未加密的&#xff0c;安全性较差&#xff0c;HTTPS&#xff08;SSLHTTP&#xff09; 数据传输过程是加密的&#xff0c;安全性较好。 使用 HTTPS 协议需要到 CA&#xff08;Certificate Authority&#xff0c;数字证书认证机构&#xff09; …

【Threejs基础教程-光影篇】5.2 Threejs 阴影系统

5.2 Threejs阴影系统 学习ThreeJS的捷径在用光影系统之前threejs是实时光影web端目前没有优质的实时光影实时光影会大幅增加渲染压力没有独显的电脑不建议添加实时光影 阴影配置什么样的灯光可以产生阴影什么样的物体可以产生阴影和接受阴影注意开启阴影渲染灵活运用阴影 平行光…

判断一个数据能否同时被3和5整除

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int a 0;//提示用户printf("请输入一个整数\n");//获取用户输入数据&#xff1b;scanf("%d", &am…

Spring Boot项目启动过程中为什么日志打印没有显示完整包名呢?

一、前言 不知道大家注意过没有&#xff0c;在Spring Boot项目启动过程中日志打印并没有显示完整的报名&#xff0c;而是显示一些o.a.c&#xff0c;o.s.web形式的包名&#xff0c;如下图&#xff1a; 这是为什么呢&#xff1f; 二、原理 首先&#xff0c;我们先看一下Spring…

WordPress AutomaticPlugin SSRF漏洞复现(CVE-2024-27954)

0x01 产品简介 WordPress是一款免费开源的内容管理系统(CMS),最初是一个博客平台,但后来发展成为一个功能强大的网站建设工具,适用于各种类型的网站,包括个人博客、企业网站、电子商务网站等,并逐步演化成一款内容管理系统软件。 0x02 漏洞概述 WordPress AutomaticPlu…

01-XML-04XML处理

XML处理 DOM DOM解析要求解析器将整个XML文件全部加载到内存中&#xff0c;生成一个Document对象。 优点&#xff1a;元素和元素之间保留结构&#xff0c;关系&#xff0c;可以针对元素进行增删改查操作。 缺点&#xff1a;如果XML文件过大&#xff0c;可能会导致内存溢出。SA…

【QT入门】 QListWidget各种常见用法详解之列表模式

往期回顾 【QT入门】 Qt代码创建布局之setLayout使用-CSDN博客 【QT入门】 Qt代码创建布局之多重布局变换与布局删除技巧-CSDN博客 【QT入门】 QTabWidget各种常见用法详解-CSDN博客 【QT入门】 QListWidget各种常见用法详解之列表模式 QListWidget有列表和图标两种显示模式&a…

springboot论坛管理系统

论坛管理系统 摘要&#xff1a; 在社会快速发展的影响下&#xff0c;论坛管理系统继续发展&#xff0c;使论坛管理系统的管理和运营比过去十年更加信息化。依照这一现实为基础&#xff0c;设计一个快捷而又方便的网上论坛管理系统是一项十分重要并且有价值的事情。对于传统的论…