虚拟列表本质以及解决方式

news2024/11/17 9:52:28

前言

简述:
	虚拟列表是一种优化长列表渲染的技术,它可以在保持流畅性的同时,渲染大量的数据。
	在传统的列表渲染中,如果列表非常长,会导致渲染时间过长,页面卡顿,用户体验变得非常差。而虚拟列表则是只渲染可见区域内的数据,而非全部渲染,这样就可以大大提高渲染效率,保持页面流畅性。
场景:
	虚拟列表技术在大数据量列表渲染场景中应用广泛,例如电商商品列表、社交动态列表
原理:
	虚拟列表的实现原理一般是通过计算容器的高度和每个列表项的高度,来确定当前可见区域内需要渲染的列表项数量和位置。

解决方式

虚拟列表实现原理
vue-virtual-scroller 方案

模拟数据

可以使用mock模拟数据、接口模拟数据或者前端封装一个自调用函数塞数据

	const data = []
   // 循环十万次
    for (let i = 1; i <= 100000; i++) {
      // 循环添加十万条数据
      data.push({ id: i, name: `列表项${i}`, value: i })
    }

虚拟列表实现原理

  1. 简述

    	虚拟列表容器:类似“视口”,视口的高度取决于一次展示几条数据
    	比如视口只能看到10条数据,一条40像素,10条400像素
    
  2. 思路

    	一个父级盒子和两个子盒子{
    		父级盒子滚动自适应,高度为10条数据的高度,相对定位
    		一个子盒子为空,具备10万条数据的高度,让父盒子滚动
    		一个子盒子绝对定位:高度为10条数据的高度
    	}
    	父级盒子添加ref属性用于获取滚动距离scrollTop,
    	监听滚动事件,
    	通过scrollTop值计算当前需要显示的10条数据,在绝对定位的子盒子中展示(计算属性)
    	如下图:
    

    在这里插入图片描述

  3. 代码

<template>
 <div class="main-conent main-conent-screen main-conent-bgFFF main-conent-borderradius">
   <h2>虚拟列表-原理</h2>
   <!--
   虚拟列表容器:类似“视口”,视口的高度取决于一次展示几条数据
   比如视口只能看到10条数据,一条40像素,10400像素
   故,视口的高度为400像素,注意要开定位和滚动条
 -->
   <div
     ref="viewport"
     class="viewport"
     :style="{ height: itemHeight * count + 'px' }"
     @scroll="handleScroll"
   >
     <!-- 占位 dom 元素,其高度为所有的数据的总高度 -->
     <div class="placeholder" :style="{ height: allListData.length * itemHeight + 'px' }" />
     <!-- 内容区,展示10条数据,注意其定位的top值是变化的 -->
     <div class="list" :style="{ top: topVal + 'px' }">
       <!-- 每一条(项)数据 -->
       <div
         v-for="item in showListData"
         :key="item.id"
         class="item"
         :style="{ height: itemHeight + 'px' }"
       >
         {{ item.name }}
       </div>
     </div>
   </div>
 </div>
</template>
<script>
import axios from 'axios'
import { getData } from '@/service/user'
export default {
 data() {
   return {
     allListData: [],
     itemHeight: 40, // 每一条(项)的高度,比如 40 像素
     count: 10, // 一屏展示几条数据
     startIndex: 0, // // 开始位置的索引
     endIndex: 20, // 结束位置的索引
     topVal: 0 // 父元素滚动位置
   }
 },
 computed: {
   showListData() {
     return this.allListData.slice(this.startIndex, this.endIndex)
   }
 },
 mounted() {
   this.getList()
 },
 methods: {
   async getList() {
     const res = await getData('/user/large-data')
     this.allListData = res.data
   },
   handleScroll() {
     // 非空判断
     const viewport = this.$refs.viewport
     if (!viewport) return
     // 获取滚动距离
     const scrollTop = viewport.scrollTop
     // 计算起始下标和结束下标,用于 computed 计算
     this.startIndex = Math.floor(scrollTop / this.itemHeight) || 0
     this.endIndex = this.startIndex + this.count + 10
     // 动态更改定位的 top 值,确保联动,动态展示相应内容
     this.topVal = viewport.scrollTop
   }
 }
}
</script>
<style scoped lang="scss">
// 虚拟列表容器盒子
.viewport {
 box-sizing: border-box;
 width: 240px;
 border: solid 1px #000000;
 // 开启滚动条
 overflow-y: auto;
 // 开启相对定位
 position: relative;
 .list {
   width: 100%;
   height: auto;
   // 搭配使用绝对定位
   position: absolute;
   top: 0;
   left: 0;
   .item {
     box-sizing: border-box;
     width: 100%;
     height: 40px;
     line-height: 40px;
     text-align: center;
     // 隔行变色
     &:nth-child(even) {
       background: #c7edcc;
     }
     &:nth-child(odd) {
       background: pink;
     }
   }
 }
}
</style>

VueUse方案解决

  1. 官网:https://github.com/Akryum/vue-virtual-scroller/tree/v1/packages/vue-virtual-scroller
  2. 使用
    	npm i vue-virtual-scroller
    	import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
    	import { RecycleScroller } from 'vue-virtual-scroller'
    	// 另外还有DynamicScroller
    
  3. 代码
    	注意事项:RecycleScroller模式下需要有item-size和外层父级盒子的高度
    
    <template>
      <div class="main-conent main-conent-screen main-conent-bgFFF main-conent-borderradius">
        <h2>虚拟列表-原理</h2>
        <RecycleScroller
          v-slot="{ item }"
          class="virtual-list"
          :items="items"
          :item-size="40"
          key-field="id"
        >
          <div class="user">
            {{ item.name }}
          </div>
        </RecycleScroller>
      </div>
    </template>
    <script>
    import { getData } from '@/service/user'
    import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
    import { RecycleScroller } from 'vue-virtual-scroller'
    
    export default {
      components: {
        RecycleScroller
      },
      data() {
        return {
          // items 要在滚动条中显示的项目列表
        //   itemSize 以像素为单位显示项目的高度(或水平模式下的宽度),用于计算滚动大小和位置
          items: [{
            id: 0,
            name: 1
          }]
        }
      },
      mounted() {
        this.getList()
      },
      methods: {
        async getList() {
          const res = await getData('/user/large-data')
          this.items = res.data
        }
      }
    }
    </script>
    <style scoped lang="less">
    .main-conent{
        height: 400px;
        box-sizing: border-box;
        width: 240px;
        border: solid 1px #000000;
        .user{
            height: 40px;
            width: 100%;
            background: aliceblue;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        /deep/ .vue-recycle-scroller__item-view{
            display: flex;
            align-items: center;
            justify-content: center;
            height: 40px;
        }
    }
    </style>
    

拓展

VueUse的useVirtualList也可以解决大数据虚拟列表

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

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

相关文章

AVL 树的初步认识与基本操作

历史 AVL 树是一种自平衡二叉搜索树&#xff0c;由托尔哈斯特罗姆在 1960 年提出并在 1962 年发表。它的名字来源于发明者的名字&#xff1a;Adelson-Velsky 和 Landis&#xff0c;他们是苏联数学家&#xff0c;于 1962 年发表了一篇论文&#xff0c;详细介绍了 AVL 树的概念和…

nginx配置https 访问

nginx 解压目录有configure文件 [rootoracledb10 ~]# which nginx1、检查nginx是否包含http_ssl_module 模块 如果出现 --with-http_ssl_module 就是已经安装了[rootoracledb10 sbin]# pwd /usr/local/nginx/sbin [rootoracledb10 sbin]# nginx -V nginx version: nginx/1.23…

技术分享| 二进制部署MySQL

一、介绍 ​MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#x…

华为手环8全新炫酷表盘上线,这些免费表盘,你绝对不能错过

在现今忙碌的生活节奏中&#xff0c;保持身心健康已逐渐成为大众的共同追求。华为手环8以时尚的设计、轻巧的体积、精确的传感器、丰富的健康模式以及智慧生活的无缝拓展&#xff0c;成为了潮流先锋达人的理想之选。华为手环8还支持多种表盘样式&#xff0c;满足不同用户的个性…

Vue开发中Jwt的使用

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Vue》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这个专栏…

ai智能语音机器人必须具备的功能

近年来&#xff0c;大多数互联网公司都进入了智能化领域。 随着人工智能技术的不断升级和突破&#xff0c;智能出境行业涌现出许多新品牌。 这些品牌有的以价格取胜&#xff0c;有的以产品性能取胜&#xff0c;这确实给消费者增加了很多选择。 ​ 然而&#xff0c;智能外呼产品…

【Java每日一题】——第二十八题:编程定义一个学生类汽车类Car(2023.10.12)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

史上最全,最详细SQL基础

SQL基础 一、 建库建表 1.1 创建数据库 创建数据库模板&#xff1a; create database 数据库名称 --创建数据库 on primary (name --数据库的逻辑名称filename --物理存放位置及物理文件名称(Student_info.m…

spark中的shuffle简述 那些会导致shuffle的算子

shuffle操作说白了就是重分区操作 在Apache Spark中&#xff0c;任务之间的依赖关系主要分为两类&#xff1a;宽依赖&#xff08;Wide Dependency&#xff09;和窄依赖&#xff08;Narrow Dependency&#xff09;。这两者之间的主要区别在于它们对任务之间数据的依赖性以及执行…

JNI中调用Java函数

文章目录 一、JNI 注册二、JNI 调用 Java 函数1、实例2、总结3、参考 三、JNI 数据传递四、JNA五、图像传递 一、JNI 注册 JNI 分成静态注册和动态注册 静态注册 cpp 实现 JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv *env, jobject…

【TensorFlow2 之012】TF2.0 中的 TF 迁移学习

#012 TensorFlow 2.0 中的 TF 迁移学习 一、说明 在这篇文章中&#xff0c;我们将展示如何在不从头开始构建计算机视觉模型的情况下构建它。迁移学习背后的想法是&#xff0c;在大型数据集上训练的神经网络可以将其知识应用于以前从未见过的数据集。也就是说&#xff0c;为什么…

omnipathr官网教程 mistr

github python版本 omnipath tutorials Issue #17 saezlab/omnipath (github.com) R版本 saezlab/OmnipathR: R client for the OmniPath web service (github.com)https://github.com/saezlab/OmnipathR GitHub - saezlab/OmnipathR: R client for the OmniPath web s…

Prettier插件使用

一、前言 由于之前使用的Beautify格式化插件已经没有在维护了&#xff0c;所以这里再分享一个Formatter插件-Prettier。 二、插件安装 首先在扩展(ctrlShiftX)中搜索关键词Prettier&#xff0c;点击安装。 三、插件使用配置 首先在VSCode编辑器中依次打开菜单文件-首选项-…

Oauth2.0单点登录的解决方案 安当加密

上海安当技术有限公司的ASP身份认证系统提供针对Oauth2.0单点登录的解决方案。该解决方案可以帮助客户实现以下目标&#xff1a; 统一的用户管理&#xff1a;Oauth2.0单点登录可以提供一个统一的用户管理平台&#xff0c;使得用户只需要在一个平台上进行注册和身份认证&#x…

基于Java使用SpringBoot+Vue框架实现的前后端分离的美食分享平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 在当今社会&#xff0…

打造类ChatGPT服务,本地部署大语言模型(LLM),如何远程访问?

ChatGPT的成功&#xff0c;让越来越多的人开始关注大语言模型&#xff08;LLM&#xff09;。如果拥有了属于自己的大语言模型&#xff0c;就可以对其进行一些专属优化。例如&#xff1a;打造属于自己的AI助理&#xff0c;或是满足企业自身的业务及信息安全需求。 所以&#xff…

天猫商品评论数据接口,天猫商品评论API接口,天猫API接口

天猫商品评论内容数据接口的步骤&#xff0c;但是可以提供淘宝商品评论内容数据接口的步骤&#xff1a; 授权获得淘宝开放平台API所需的权限。获取AppKey和AppSecret等认证信息。发送HTTP请求&#xff0c;获取所需评价信息。对获取到的评价信息进行处理和解析。结果处理&#…

行业顶流|AI数字人直播,低成本、高回报的新趋势

去年&#xff0c;元宇宙的概念炒得特别火&#xff0c;落地却寥寥无几&#xff0c;今年的AI数字人是否也只是一时炒作的概念呢&#xff1f; 在这个信息时代&#xff0c;科技的发展总是伴随着各种概念的冒起。元宇宙作为其中之一&#xff0c;的确在一瞬间扑面而来&#xff0c;引…

《机器学习》第5章 神经网络

文章目录 5.1 神经元模型5.2 感知机与多层网络5.3 误差逆传播算法5.4 全局最小与局部最小5.5 其他常见神经网络RBF网络ART网络SOM网络级联相关网络Elman网络Boltzmann机 5.6 深度学习 5.1 神经元模型 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络&#xff0c;它…

数字化转型,河北吉力宝—传统行业的自我救赎新标杆

近年来,国家出台了各项政策支持企业数字化转型,“十四五”计划更是将建设数字经济作为重要发展目标,中国人工智能产业进入爆发式增长阶段,市场潜力巨大。随着数字化时代的到来&#xff0c;加快发展数字经济成为把握新一轮科技革命和产业变革新机遇的战略选择。 健康卫生事件后…