Vue2 - vue-virtual-scroller 长列表优化原理

目录

  • 1,效果展示
  • 2,原理
    • 2.1,滚动条的处理
    • 2.2,展示内容处理
  • 3,实现

vue-virtual-scroller

1,效果展示

在这里插入图片描述

1w 条数据无压力,看下初始渲染时间 Rendering 对比:

在这里插入图片描述
在这里插入图片描述

2,原理

目标:只加载在可视容器中的列表项。

实现:

2.1,滚动条的处理

  1. 为了保证滚动条正确显示和滑动,需要按照原本的数据量来计算滑动内容区域 wrapper 的真实高度,
  2. wrapper 外层的 container 作为滑动容器,设置 overflow:auto + 定高(比如500px)。

2.2,展示内容处理

最终目标:只展示可视区域内的 item,所以肯定会对源数据进行截取,需要计算出 startIndexendIndex

  1. 为了保证只显示可视区域内的 item,可通过定位将每个 item 的初始位置都固定在第一行(top: 0; left: 0)。
  2. 在对每个 item 设置不同的偏移量 transform: translateY(index * itemHeight); 就可以正常展示了。
  3. 滑动时,需要根据滑动的距离 container.scrollTop 来重新计算 startIndex。再加上 container.clientHeight 可以计算出 endIndex
  4. 则可得出初始偏移量:transform: translateY(startIndex* itemHeight);

3,实现

<!-- 父组件 -->
<template>
  <div>
    <RecycleScroller :items="list" :itemSize="54" v-slot="{ item }" class="scroller">
      <div class="item-box">
        <span>{{ item.id }}</span>
        <span>{{ item.name }}</span>
      </div>
    </RecycleScroller>
  </div>
</template>

<script>
import RecycleScroller from './components/RecycleScroller.vue'

const arr = []
for (let index = 0; index < 10000; index++) {
  arr[index] = {
    id: 'id' + index,
    name: `name` + index
  }
}

export default {
  components: {
    RecycleScroller
  },
  data() {
    return {
      list: arr
    }
  }
}
</script>
<style>
.scroller {
  width: 200px;
  height: 500px;
  overflow: auto;
}

.item-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px;
}
</style>
<!-- RecycleScroller.vue -->
<template>
  <div class="recycle-container" ref="container" @scroll="setPool">
    <div class="recycle-wrapper" :style="{ height: totalSize }">
      <div v-for="poolItem in pool" :key="poolItem.keyField" class="recycle-item" :style="{ transform: `translateY(${poolItem.position}px)` }">
        <slot :item="poolItem.item"></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    items: {
      // 数据列表
      type: Array,
      default: () => []
    },
    itemSize: {
      // 每条数据的高度
      type: Number,
      default: 50
    },
    keyField: {
      // items 中的唯一标识作为 key
      type: String,
      default: 'id'
    }
  },
  data() {
    return {
      pool: [] // 会被渲染的列表内容
    }
  },
  computed: {
    totalSize() {
      return this.items.length * this.itemSize + 'px'
    }
  },
  methods: {
    setPool() {
      const scrollTop = this.$refs.container.scrollTop
      const clientHeight = this.$refs.container.clientHeight
      
      let startIndex = Math.floor(scrollTop / this.itemSize) || 0
      let endIndex = Math.ceil((scrollTop + clientHeight) / this.itemSize)
      const startPosition = startIndex * this.itemSize
      
      // 每次都重新计算 item 对应的位置。
      this.pool = this.items.slice(startIndex, endIndex).map((item, index) => ({
        item,
        position: startPosition + this.itemSize * index
      }))
    }
  },
  mounted() {
    this.setPool()
  }
}
</script>

<style scoped>
.recycle-container {
  overflow: auto;
}
.recycle-wrapper {
  position: relative;
}
.recycle-item {
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
</style>

如果担心滑动太快导致的白屏问题(没有计算渲染出来),可以在前后各增加10条数据,一般就没有问题了。

以上。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测

多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测 目录 多维时序 | Matlab实现DBO-BiLSTM蜣螂算法优化双向长短期记忆神经网络多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现DBO-BiLSTM多变量时间序…

ActiveMQ|01-ClassicArtemis功能介绍

接上篇-MQ消息队列主流消息服务规范及代表产品&#xff0c;ActiveMQ就是基于JMS消息服务规范的消息中间件组件&#xff0c;主要应用在分布式系统架构中&#xff0c;帮助构建高可用、 高性能、可伸缩的企业级面向消息服务的系统 本文速览&#xff1a; JMS对象模型ActiveMQ的功…

关于axios给后端发送数据的问题

这里需要用的插件&#xff1a;qs.js&#xff0c;是前端给后端发送的数组&#xff0c;需要序列化所以要用到这个插件&#xff0c;这里就提取连接在这里&#xff0c;需要的自提&#xff0c;需要导如进来&#xff0c;别忘记了 链接&#xff1a;https://pan.baidu.com/s/1qyD8v9wfd…

极简云验证商业版已经开源源码

极简云商业版已经开源 解绑卡密 查询卡密 总体来说还是很完善的 对接例子网盘里有 用户注册需要配置邮箱 上网页 QQ 邮箱标准版开启 SMTP 然后生成授权码后台发信邮箱里填就对了 实在不会配置邮箱的 可以下载网盘里的reg.php 把 reg.php 上传源码里的 user 目录 之后注册就不需…

论文阅读《thanking frequency fordeepfake detection》

这篇论文从频域的角度出发&#xff0c;提出了频域感知模型用于deepfake检测的模型 整体架构图&#xff1a; 1.FAD&#xff1a; 频域感知分解&#xff0c;其实就是利用DCT变换&#xff0c;将空间域转换为频域&#xff0c;变换后的图像低频信息在左上角&#xff0c;高频信息在右…

TCP 三次握手以及滑动窗口

TCP 三次握手 简介&#xff1a; TCP 是一种面向连接的单播协议&#xff0c;在发送数据前&#xff0c;通信双方必须在彼此间建立一条连接。所谓的 “ 连接” &#xff0c;其实是客户端和服务器的内存里保存的一份关于对方的信息&#xff0c;如 IP 地址、端口号等。 TCP 可以…

如何使用Stable Diffusion的ReActor换脸插件

ReActor插件是从roop插件分叉而来的一个更轻便、安装更简单的换脸插件。操作简单&#xff0c;非常容易上手&#xff0c;下面我们就介绍一下&#xff0c;如何将ReActor作为stable diffusion的插件进行安装和使用。 一&#xff1a;安装ReActor插件 项目地址&#xff1a;https:/…

Docker部署Stable-Diffusion-webui

前排提示&#xff1a;如果不想折腾&#xff0c;可直接跳到最后获取封装好的容器&#xff0c;一键运行 :D 前言 乘上AI生成的快车&#xff0c;一同看看沿途的风景。 启一个miniconda容器 docker run -itd -v 宿主机内SD项目路径:/tmp --gpus all --ipc host -p 7860:7860 con…

15- OpenCV:模板匹配(cv::matchTemplate)

目录 1、模板匹配介绍 2、cv::matchTemplate 3、模板匹配的方法&#xff08;算法&#xff09; 4、代码演示 1、模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。 它可以在一幅图像中寻找与给定模板最相似的部分。 模板匹配的步骤&#xff1a; &a…

windows 搜狗输入法几款 简洁皮肤

预览 下载地址 见附件 使用方法 下载到本地&#xff0c;解压&#xff0c;双击直接使用 分流下载链接 windows搜狗输入法皮肤.zip - 蓝奏云

SQL - 事务控制

SQL - 事务控制 文章目录 SQL - 事务控制TCL - 事务事务的边界事务的特性事务的应用 事务隔离等级MySQL支持四种隔离级别 TCL - 事务 **模拟场景&#xff1a;**生活当中转账是转账方账户扣钱&#xff0c;收账方账户加钱。用数据库操作来模拟现实转账。 数据库模拟&#xff1a…

etcd未授权到控制k8s集群

在安装完 K8s 后&#xff0c;默认会安装 etcd 组件&#xff0c;etcd 是一个高可用的 key-value 数据库&#xff0c;它为 k8s 集群提供底层数据存储&#xff0c;保存了整个集群的状态。大多数情形下&#xff0c;数据库中的内容没有加密&#xff0c;因此如果黑客拿下 etcd&#x…

02-Redis持久化、主从与哨兵架构详解

文章目录 Redis持久化RDB快照&#xff08;snapshot&#xff09;bgsave的写时复制(COW)机制AOF&#xff08;append-only file&#xff09;AOF重写RDB 和 AOF &#xff0c;我应该用哪一个&#xff1f; Redis 4.0 混合持久化Redis数据备份策略&#xff1a; Redis主从架构redis主从…

选择排序(堆排序和topK问题)

选择排序 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完 。 如果我们用扑克牌来举例&#xff0c;那么选择排序就像是提前已经把所有牌都摸完了&#xff0c;而再进行牌…

消息中间件之RocketMQ(三)

常见问题 1.重复消费 产生的原因是发送消息时采用了多数分布式消息中间件产品提供的最少一次(at least once)的投递保障&#xff0c;对于这个问题最常见的解决方案,就是消息消费端实现业务幂等&#xff0c;只要保持幂等性&#xff0c;不管来多少条重复消息&#xff0c;最后处…

视频监控方案设计:EasyCVR视频智能监管系统方案技术特点与应用

随着科技的发展&#xff0c;视频监控平台在各个领域的应用越来越广泛。然而&#xff0c;当前的视频监控平台仍存在一些问题&#xff0c;如视频质量不高、监控范围有限、智能化程度不够等。这些问题不仅影响了监控效果&#xff0c;也制约了视频监控平台的发展。 为了解决这些问…

【LMDeploy 大模型量化部署实践】学习笔记

参考学习教程【LMDeploy 的量化和部署】 理论 作业 使用 LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署 InternLM-Chat-7B 模型&#xff0c;生成 300 字的小故事 本地对话 API服务 Client 命令 端口转发 网页Gradio

C语言每日一题(48)回文链表

力扣 234 回文链表 题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1…

【渗透测试】借助PDF进行XSS漏洞攻击

简介 在平时工作渗透测试一个系统时&#xff0c;常常会遇到文件上传功能点&#xff0c;其中大部分会有白名单或者黑名单机制&#xff0c;很难一句话木马上传成功&#xff0c;而PDF则是被忽略的一个点&#xff0c;可以让测试报告更丰富一些。 含有XSS的PDF制作步骤 1. 编辑器…

JavaSE基础学习

一、编程入门 二、Java语言概述 三、Java基本语法 四、程序流程控制 五、数组 六、面向对象(上) 数组工具类的封装: 七、面向对象(中) 八、面向对象(下) 九、异常处理 十、多线程 十一、常用类 十二、枚举类与注解 十三、集合 十四、泛型 十五、IO流 十六、网络编程 十七、反射…