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

虚拟列表的实现(简单易懂)

起因:

app开发过程中遇到需要渲染3000行的列表,页面直接卡顿,所以开始研究起虚拟列表

实现前提条件:

item项等高列表

实现思路:

首先是dom结构:

  1. 定义一个容器(固定高度),监听滚动事件
  2. 容器定义一个内部滚动容器,高度等于列表个数 * 每项高度
  3. 内部滚动容器里面再定义一个容器,具有transform: translateY属性,根据用户滚动动态改变位置,是真正展示的窗口
  4. 再里面就是展示的item项列表

然后是实现逻辑:

  1. 默认展示50条(条数不固定,保证展示能铺满屏幕即可),渲染完成后获取item项高度和最外面容器高度,根据它俩计算出应该展示的item项 Math.ceil(this.containerHeight / this.itemHeight)
  2. 用户滚动时在滚动事件里根据scrollTop设置translateY属性,用scrollTop % this.itemHeight去掉多余高度,保证会在边界上 translateY = scrollTop - (scrollTop % this.itemHeight)
  3. 用户滚动时在滚动事件里根据scrollTop和item项高度判断应该展示的起始项index startIndex = Math.floor(scrollTop / this.itemHeight)
  4. 最后重新渲染列表item项,渲染 startIndex + Math.ceil(this.boxHeight / this.itemHeight)之间的item项

代码展示:

<script lang="ts" setup name="virtual-list-comp">
import { onBeforeMount, ref, computed, nextTick, Ref, onMounted } from 'vue'
import { throttle } from '@/util/util'const props = defineProps({list: {type: Array,default: () => [],},
})// 容器高度
const containerHeight = ref(0)
// item项高度(默认取第一个)
const itemHeight = ref(0)
const getHeight = computed(() => {return itemHeight.value > 0 ? props.list.length * itemHeight.value + 'px' : 'auto'
})// 真正展示的列表
const showList: Ref<any[]> = ref([])
// 需要渲染的起始项
const startIndex = ref(0)
const itemNum = computed(() => {if (containerHeight.value && itemHeight.value) {return Math.ceil(containerHeight.value / itemHeight.value)}return 50
})
const translateY = ref(0)const initShowList = () => {showList.value = props.list.slice(startIndex.value, startIndex.value + itemNum.value)
}
// 获取盒子高度和item项高度
const initHeight = () => {containerHeight.value = document.querySelector('.virtual-list')?.clientHeight || 0itemHeight.value = document.querySelector('.virtual-list__item')?.clientHeight || 0
}const handleScroll = (e: any) => {const { scrollTop } = e.target// 获取 virtual-list__transform 这个展示视口的偏移值translateY.value = scrollTop - (scrollTop % itemHeight.value)startIndex.value = Math.floor(scrollTop / itemHeight.value)initShowList()
}onBeforeMount(async () => {initShowList()await nextTick()initHeight()
})
onMounted(() => {document.querySelector('.virtual-list__container')?.addEventListener('scroll', throttle(handleScroll, 10))
})
</script><template><div class="virtual-list h-full"><divclass="virtual-list__container overflow-y-scroll":style="{height: containerHeight + 'px',}"><div class="virtual-list__scroll" :style="{ height: getHeight }"><div class="virtual-list__transform" :style="{ transform: `translateY(${translateY}px)` }"><div v-for="(item, index) of showList" :key="index" class="virtual-list__item"><slot name="item" :item="item"></slot></div></div></div></div></div>
</template>

相关文章:

虚拟列表的实现(简单易懂)

起因&#xff1a; app开发过程中遇到需要渲染3000行的列表&#xff0c;页面直接卡顿&#xff0c;所以开始研究起虚拟列表 实现前提条件&#xff1a; item项等高列表 实现思路&#xff1a; 首先是dom结构&#xff1a; 定义一个容器&#xff08;固定高度&#xff09;&#…...

【WordPress】如何在WordPress中实现真·页面路由

这篇文章也可以在我的博客中查看 页面路由 是什么 页面路由是指从url顺着网线砍到网站内容的途径&#xff0c;说人话就是地址与页面的映射。 就像真实世界的地址一样&#xff0c;我要找你&#xff0c;必须知道你的地址。 在网站中&#xff0c;通过地址找内容的机制&#xf…...

Android界面设计与用户体验

Android界面设计与用户体验 1. 引言 在如今竞争激烈的移动应用市场&#xff0c;提供优秀的用户体验成为了应用开发的关键要素。无论应用功能多么强大&#xff0c;如果用户界面设计不合理&#xff0c;用户体验不佳&#xff0c;很可能会导致用户流失。因此&#xff0c;在Androi…...

基于 FFmpeg 的跨平台视频播放器简明教程(八):音画同步

系列文章目录 基于 FFmpeg 的跨平台视频播放器简明教程&#xff08;一&#xff09;&#xff1a;FFMPEG Conan 环境集成基于 FFmpeg 的跨平台视频播放器简明教程&#xff08;二&#xff09;&#xff1a;基础知识和解封装&#xff08;demux&#xff09;基于 FFmpeg 的跨平台视频…...

【NLP pytorch】基于BiLSTM-CRF模型医疗数据实体识别实战(项目详解)

基于BiLSTM-CRF模型医疗数据实体识别实战 1数据来源与加载1.1 数据来源1.2 数据类别名称和定义1.3 数据介绍2 模型介绍2 数据预处理2.1 数据读取2.2 数据标注2.3 数据集划分2.4 词表和标签的生成3 Dataset和DataLoader3.1 Dataset3.2 DataLoader4 BiLSTM模型定义5 CRF模型6 模型…...

人工智能原理(1)

*请注意&#xff0c;本文仅供学习使用* 目录 一、人工智能发展 1、孕育期 2、摇篮期 3、形成期 4、发展期&#xff08;1970-1979&#xff09; 5、实用期 6、稳步发展期 二、何为人工智能 1、智能的主要观点 2、智能定义 3、人工智能定义 三、人工智能研究方法 1、…...

预测成真,国内传来三个消息,中国年轻人变了,创新力产品崛起

中国的年轻人真的变了&#xff01; 最近&#xff0c;国内传来三个消息&#xff0c;让外媒的预测成真。 第一&#xff0c;奥迪要开始用国产车的平台了。这里需要说明的是新能源汽车&#xff0c;奥迪也曾多次公开表示&#xff0c;承认了当前中国新能源汽车核心技术上的领先。 第…...

维深(Wellsenn):2023中国消费端VR内容开发商调研报告(附下载

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 国内互联网大厂商入局VR&#xff0c;字节跳动、网易表态明确。字节跳动2021年收购国内头部VR硬件厂商PICO后&#xff0c;加速构建VR内容生态&#xff0c;2021年 成立海南创见未来当前已推出VR视频应用…...

redis事务管理详解

事务管理 事务管理乐观锁与悲观锁watch命令实现乐观锁watch命令示例 事务管理 Redis 提供了事务管理功能&#xff0c;可以通过 Redis 的 MULTI、EXEC、WATCH 和 DISCARD 命令来实现。 开启事务&#xff1a; 使用 MULTI 命令开始一个事务&#xff0c;表示接下来执行的命令都属于…...

国产低功耗蓝牙HS6621CxC/6621Px系列支持Find My网络功能方案芯片

目录 什么是“Find My“&#xff1f;HS6621系列简介 什么是“Find My“&#xff1f; “Find My”是苹果公司于19年前推出的针对失物追踪&#xff0c;Find My iPhone&#xff08;查找我的iPhone&#xff09;和Find My Friends&#xff08;查找朋友&#xff09;的结合体应用。为…...

【openGauss】分区表的介绍与使用

一、openGauss分区表介绍 在openGauss中&#xff0c;数据分区是在一个节点内部对数据按照用户指定的策略做进一步的水平分表&#xff0c;将表中的数据按照指定方式划分为多个互不重叠的部分。 对于大多数用户使用场景&#xff0c;分区表和普通表相比具有以下优点&#xff1a; …...

代码随想录算法训练营day57

文章目录 Day57回文子串题目思路代码 最长回文子序列题目思路代码 Day57 回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; 题目 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。…...

【基础类】—前后端通信类系统性学习

一、什么是同源策略及限制 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。源&#xff1a;协议、域名和端口&#xff0c; 默认端口是80 三者有一个不同&#xff0c;即源不同&#xff0c;就是跨域 ht…...

vite项目中使用@代表根路径

1.配置vite.config.ts import { defineConfig } from vite import vue from vitejs/plugin-vue import path from pathexport default defineConfig({plugins: [vue()],resolve: {alias:{: path.resolve(__dirname, src) }} })2.报错path和__dirname 找不到模块“path”或其相…...

冶金化工操作VR虚拟仿真实验软件提高员工们协同作业的配合度

对于高风险行业来说&#xff0c;开展安全教育培训是企业的重点工作&#xff0c;传统培训逐渐跟不上时代变化和工人需求&#xff0c;冶金安全VR模拟仿真培训系统作为一种新型的教育和培训工具&#xff0c;借助VR虚拟现实技术为冶金行业的工人提供一个安全、高效的培训环境。 冶金…...

SQL Server数据库 -- 索引与视图

文章目录 一、索引 聚集索引非聚集索引二、视图三、自定义函数 标量函数表值函数四、游标五、总结 前言 在学习完创建库表、查询等知识点后&#xff0c;为了更加方便优化数据库的存储和内容&#xff0c;我们需要学习一系列的方法例如索引与视图等等&#xff0c;从而使我们更加…...

2023 java web面试秘籍

目录 第一章&#xff1a;Java Web基础知识1.介绍3.Java Web基本概念 4.常见面试问题第二章&#xff1a;Java Web核心概念和技术1.介绍3.Servlet和JSP4.Web安全5.常见面试问题 第三章&#xff1a;Java Web高级概念和技术1.介绍3.Spring框架4.安全性5.常见面试问题 第四章&#x…...

2023-08-05力扣今日二题

链接&#xff1a; 剑指 Offer 18. 删除链表的节点 题意&#xff1a; 如题 解&#xff1a; 基础链表操作 实际代码&#xff1a; #include<iostream> using namespace std; struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {} }; Li…...

stl_list类(使用+实现)(C++)

list 一、list-简单介绍二、list的常用接口1.常见构造2.iterator的使用3.Capacity和Element access4.Modifiers5.list的迭代器失效 三、list实现四、vector 和 list 对比五、迭代器1.迭代器的实现2.迭代器的分类&#xff08;按照功能分类&#xff09;3.反向迭代器(1)、包装逻辑…...

利用hfish反控境外攻击源主机

导师给了7个网络安全课题选题&#xff0c;本想和他聊了下思路&#xff0c;他一挥手让我先做出点东西再来聊就把我打发走了…… 正好前段时间阿里云到校做推广&#xff0c;用优惠卷薅了一台云服务器&#xff0c;装了hfish先看下情况 没想到才装上没两天数据库就爆了&#xff0…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...