当前位置: 首页 > news >正文

vue2 虚拟列表(优化版)

作用:

虚拟列表是优化长列表的一种手段,防止列表存在过多的dom元素导致页面卡顿(包扣移动端下拉到底加载下一页这种列表加载的dom元素多了一样会卡)。

原理:

如上图简单地说就是以 <div class=''list-view">作为固定窗口用来展示看到的数据。

用<div class="list-view-phantom">来撑起固定窗口的高度来出现滚动条。

用<ul class="list-view-content">来存放数据,并且让他随着滚动条一起动,达到视觉上的列表滚动。

优化的问题:

在基础虚拟列表的基础上优化了如下几点

1.根据rem动态计算每一条数据在页面中对应的height和margin。

2.当窗口的resize事件触发一切数值都重新计算,让列表底部样式不出错,和滚动到底部不抖动。

3.向下滚动加载下一条数据时候卡在计算阈值内,导致底部留白太大,通过至多加载固定窗口对应展示数据的数量给追加到原本的结尾索引,达到多渲染一屏窗口的数据。

4.加载数据到最后显示暂无更多数据文案。

5.自动滚动到指定数据项的位置。

6.页面不停快速刷新导致获取不到固定窗口高度和滚动到指定位置不起作用。

实现如下:

<template><div ref="listView" class="list-view"  @scroll="handleScroll"><div class="list-view-phantom" :style="{height: `${contentHeight}px`}"></div><ul class="list-view-content" ref="content" ><li class="list-view-item" v-for="(item, index) in visibleData" :key="index">{{ item }}</li><div v-if="lastFlag" style="height:100px;line-height:50px;font-size:30px;color:black;">暂无更多数据</div></ul></div>
</template>
<script>
export default {name: 'ListView',props: {data: {type: Array,default: function() {const list = []for (let i = 0; i < 150; i++) {list.push('列表' + i)}return list}},itemHeight: {type: Number,default: 365},itemMargin: {type: Number,default: 80},},computed: {contentHeight() {return this.data.length * this.itemHeightRem + this.data.length * this.itemMarginRem;},},watch:{data:{handler(){this.$nextTick(()=>{this.init();})},deep:true},},mounted() {let that = this;this.init();window.onresize = function(){//加防抖if(that.timer){clearTimeout(that.timer);that.timer=null;}that.timer = setTimeout(() => {that.init();}, 500);}},data() {return {//列表底部增加展示数据比例bufferScale:1,timer:null,itemHeightRem:'',itemMarginRem:'',listView:null,contentView:null,visibleData: [],//滚动到指定数据项docStatusIndex:0,lastFlag:false,};},methods: {init(){this.$nextTick(()=>{let htmlFontSize = document.documentElement.style.fontSize;//使用rem的项目中,根据html的fontSize自动计算列表每一项的height和marginthis.itemHeightRem = Number((this.itemHeight/(192/parseFloat(htmlFontSize)).toFixed(2)));this.itemMarginRem = Number((this.itemMargin/(192/parseFloat(htmlFontSize)).toFixed(2)));this.listView = this.$refs.listView;this.contentView = this.$refs.content//自动滚动到指定数据索引位置this.listView.scrollTop = this.docStatusIndex * (this.itemHeightRem + this.itemMarginRem);//拦截刷新错误计算:scrollTop计算为0  或者  获取不到$refs.listView和clientHeightif(!this.listView || this.listView.clientHeight == 0 || (this.docStatusIndex > 0 && this.listView.scrollTop == 0)){setTimeout(() => {this.init();}, 300);return;}this.updateVisibleData(this.listView.scrollTop);})},updateVisibleData(scrollTop) {scrollTop = scrollTop || 0;// 取得可见区域的可见列表项数量const visibleCount = Math.ceil(this.listView.clientHeight / (this.itemHeightRem + this.itemMarginRem)); // 取得可见区域的起始数据索引let start = Math.floor(scrollTop / (this.itemHeightRem + this.itemMarginRem)); // 取得可见区域的结束数据索引let end = start + visibleCount; //防止可见区域的数据展示超出data最大范围if(end>this.data.length && start>0){return;}//显示暂无更多文案if(end == this.data.length){this.lastFlag = true;}//end之后增加至多visibleCount条数据,防止底部空白过大const belowCount = Math.min(this.data.length - end,this.bufferScale * visibleCount);end = end + belowCount;//可见区域展示的数据this.visibleData = this.data.slice(start, end); // 展示列表进行偏移this.contentView.style.webkitTransform = `translate3d(0,${scrollTop - (scrollTop % (this.itemHeightRem + this.itemMarginRem))}px,0)`; },//要加节流handleScroll() {const scrollTop = this.listView.scrollTop ;this.updateVisibleData(scrollTop);}}
}
</script>
<style  scoped>
.list-view {overflow: auto;position: relative;width: 100%;height:100%;box-sizing: border-box;
}.list-view-phantom {position: absolute;left: 0;top: 0;right: 0;z-index: -1;
}.list-view-content {top:0;left:0;right:0;position: absolute;
}.list-view-item {margin-bottom: 80px;;background-color: aqua;color: red;height:365px;line-height: 130px;width:100%;display: block;font-size: 140px;box-sizing: border-box;overflow: hidden;
}
</style>

相关文章:

vue2 虚拟列表(优化版)

作用&#xff1a; 虚拟列表是优化长列表的一种手段&#xff0c;防止列表存在过多的dom元素导致页面卡顿&#xff08;包扣移动端下拉到底加载下一页这种列表加载的dom元素多了一样会卡&#xff09;。 原理&#xff1a; 如上图简单地说就是以 <div classlist-view">作…...

从应用层到MCU,看Windows处理键盘输入 [1.在应用层调试Notepad.exe (按键消费者)]

文本编辑器/文本编辑框是应用层常见的键盘处理程序。微软泄露的WinXP源码下有文本编辑器Notepad的实现&#xff1a;Microsoft_leaked_source_code\nt5src\Source\XPSP1\NT\shell\osshell\accesory\notepad文本编辑器的实现并不复杂&#xff0c;微软又(被迫)提供了Sample&#x…...

什么是大数据?大数据能做什么

大数据发现现在如火如荼&#xff0c;也吸引了很多有志人士想要加入这个行业&#xff0c;但是在正式入行之前了解大数据是什么以及能做什么是非常重要的~ 下面我们一起来看一下~ 比较官方的定义是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff…...

Git 和 GitHub 超入门指南(四)

Git基本命令 以下是一些基本的Git命令&#xff1a; git add&#xff1a;将文件添加到Git索引中git commit&#xff1a;将索引中的文件提交到Git仓库中git status&#xff1a;查看工作目录和索引的状态git log&#xff1a;查看提交历史记录 Git高级命令 以下是一些高级的Git…...

Java 响应式编程 Reactor 框架

文章目录 Java 响应式编程 Reactor 框架FluxMono其它的关键对象Java 响应式编程 Reactor 框架 Reactor框架的核心理念是基于响应式编程的异步流处理。这意味着应用程序可以通过异步事件流来处理请求,而不是通过传统的同步请求-响应模型。在响应式编程中, 应用程序可以处理多个…...

Hazel引擎学习(十一)

我自己维护引擎的github地址在这里&#xff0c;里面加了不少注释&#xff0c;有需要的可以看看 参考视频链接在这里 很高兴的是&#xff0c;引擎的开发终于慢慢开始往深了走了&#xff0c;前几章的引擎UI搭建着实是有点折磨人&#xff0c;根据课程&#xff0c;接下来的引擎开发…...

深度学习(22):如何判断训练过程中深度学习模型损失值不再下降

2023年3月22日&#xff0c;与 chatGPT 的沟通如何判断训练过程中深度学习模型损失值不再下降在深度学习中&#xff0c;判断模型是否收敛是非常重要的&#xff0c;这可以通过监控模型损失值来实现。一般来说&#xff0c;当训练模型的损失值不再下降&#xff0c;我们就可以认为模…...

一个比较全面的C#公共帮助类

上次跟大家推荐过2个C#开发工具箱&#xff1a;《推荐一个不到2MB的C#开发工具箱&#xff0c;集成了上千个常用操作类》、《推荐一个.Net常用代码集合&#xff0c;助你高效完成业务》。 今天再给大家推荐一个&#xff0c;这几个部分代码功能有重合的部分&#xff0c;大家可以根…...

人脸识别经典网络-MTCNN(含Python源码实现)

人脸检测-mtcnn 本文参加新星计划人工智能赛道&#xff1a;https://bbs.csdn.net/topics/613989052 文章目录人脸检测-mtcnn1. 人脸检测1.1 人脸检测概述1.2 人脸检测的难点1.3 人脸检测的应用场景2. mtcnn2.1 mtcnn概述2.2 mtcnn的网络结构2.3 图像金字塔2.4 P-Net2.5 R-Net2…...

OpenCV入门(十八)快速学会OpenCV 17 直线检测

OpenCV入门&#xff08;十八&#xff09;快速学会OpenCV 17 直线检测1.霍夫直线变换概述2.霍夫变换原理3.操作实例3.1 HoughLines函数3.2 HoughLinesP函数作者&#xff1a;Xiou 1.霍夫直线变换概述 霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。霍夫变换采用…...

nginx快速入门.跟学B站nginx一小时精讲课程笔记

nginx快速入门.跟学B站nginx一小时精讲课程笔记nginx简介及环境准备nginx简介环境准备一、nginx 安装1.使用yum安装2.常用命令3.使用systemctl启动、停止、重新加载4.配置文件5.配置文件结构二、配置静态web1.静态网页配置2.listen监听3.server_name4.location三、HTTP反向代理…...

内存泄漏定位工具之 valgrind

内存泄漏检测工具 文章目录内存泄漏检测工具一、valgrind介绍1. memcheck2. cachegrind3. helgrind二、源码下载三、命令操作1.memcheck 工具四、虚拟机下使用1. x86编译2. 正常程序测试3. 申请内存不释放测试4. 内存越界的测试5. 读写已经释放的内存五、ARM平台使用1.交叉编译…...

Django(一)安装

好久没更新了 学习的内容太多了有点杂 一时不知道从何说起 !!! 对于Django我也不是很了解 在网上搜了个词条就是以下显示 我目前的了解也仅限于此 希望在接下来的学习过程中 有更多的学习体会可以和大家分享 一涉及到在对应python环境 下载东西时思维就会很混乱 这里再把之前…...

11从零开始学Java之如何正确地定义变量?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者前言在之前的文章中&#xff0c;壹哥给大家讲解了Java的第一个案例HelloWorld&#xff0c;并详细给大家介绍了Java的标识符&#xf…...

51单片机之喝水提醒器

定时器定时器介绍晶振晶体震荡器&#xff0c;又称数字电路的“心脏”&#xff0c;是各种电子产品里面必不可少的频率元器件。数字电路的所有工作都离不开时钟&#xff0c;晶振的好坏、晶振电路设计的好坏&#xff0c;会影响到整个系统的稳定性。时钟周期时钟周期也称为振荡周期…...

扒一扒抖音是如何做线程优化的

背景 最近在对一些大厂App进行研究学习&#xff0c;在对某音App进行研究时&#xff0c;发现其在线程方面做了一些优化工作&#xff0c;并且其解决的问题也是之前我在做线上卡顿优化时遇到的&#xff0c;因此对其具体实现方案做了深入分析。本文是对其相关源码的研究加上个人理…...

149.网络安全渗透测试—[Cobalt Strike系列]—[重定器/代理服务器/流量走向分析]

我认为&#xff0c;无论是学习安全还是从事安全的人多多少少都会有些许的情怀和使命感&#xff01;&#xff01;&#xff01; 文章目录一、Cobalt Strike 重定器1、Cobalt Strike 重定器简介2、重定器用到的端口转发工具二、cobalt strike重定器实验1、实验背景2、实验过程3、流…...

Qt调用Chrome浏览器

一、前言 最近有个小项目需要跳转网页&#xff0c;之前有了解过&#xff0c;但是没有在项目中使用过Qt网页嵌入&#xff1b; 结合自己之前的博客&#xff0c;有如下两种技术可以实现我的需求&#xff1a; 1、Qt–网页嵌入 2、Qt使用QAxWidget调用Windows组件 但是在实际开…...

JVM虚拟机垃圾回收机制

JVM虚拟机垃圾回收机制垃圾回收机制判断是否存活算法引用计数法可达性分析法最终判定垃圾回收算法分代收集机制空间分配担保垃圾回收机制 判断是否存活算法 java语言和我们之前学的c/c不同&#xff0c;c/c可以手动进行内存释放&#xff0c;那样随时随地就可以释放不必要的内存…...

菜鸟刷题Day3

⭐作者&#xff1a;别动我的饭 ⭐专栏&#xff1a;菜鸟刷题 ⭐标语&#xff1a;悟已往之不谏&#xff0c;知来者之可追 一.字符串压缩&#xff1a;面试题 01.06. 字符串压缩 - 力扣&#xff08;LeetCode&#xff09; 描述 字符串压缩。利用字符重复出现的次数&#xff0c;编…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...