vue大数据量列表渲染性能优化:虚拟滚动原理

前面咱完成了自定义JuanTree组件各种功能的实现。在数据量很大的情况下,我们讲了两种实现方式来提高渲染性能:前端分页和节点数据懒加载。

前端分页小节:Vue3扁平化Tree组件的前端分页实现

节点数据懒加载小节:Element Tree Plus版功能演示:数据懒加载

关于扁平化结构Tree和嵌套结构Tree组件的渲染

嵌套结构的Tree组件是一种递归渲染,性能上比起列表结构的v-for渲染比较一般。对于这种渲染方式,在数据量很大的情况下,只有通过懒加载可以提高渲染性能;而扁平化结构则有更多的选择,前端分页是一种方式,还有一种更好的选择,就是本节介绍的虚拟滚动。

在这里插入图片描述

下一小节,我们将对自定义JuanTree组件来应用虚拟滚动,解决数据量非常大的情况下的用户体验良好的高性能渲染。本小节讲原理和基本demo的实现,喜欢的点个赞,关注下,后续会更精彩!

功能演示

在这里插入图片描述

虚拟滚动的原理

在这里插入图片描述

demo实现

编写vitepress示例

在这里插入图片描述

滚动条的实现

考虑到原生滚动条太丑,我们使用element-plus提供的el-scrollbar组件,因为它简单好用且展示也很美观。

element plus在基于vite的vue3 tsx项目的整合请参考:vite tsx项目的element plus集成 - 按需引入踩坑

demo示例源码

src/components/VirtualList.vue

实现非常简单易懂!

<script setup lang="ts">
import { computed, ref } from 'vue'

const containerHeight = 24 * 12 // 容器高度
const itemHeight = 24 // 列表项高度
const visibleCount = Math.ceil(containerHeight / itemHeight) // 可视区域列表元素数量
const totalCount = 1000 // 列表元素总数
const data = ref(Array.from({ length: totalCount }).map((_, index) => ({ value: index })))
// 起始索引
const startIndex = ref(0)
// 可视区域的数据
const visibleData = computed(() => data.value.slice(startIndex.value, startIndex.value + visibleCount))
// 数据列表在Y轴的偏移量
const offsetY = ref(0)
const onScroll = (event: any) => {
  const scrollTop = event.scrollTop
  // 按照滚动的高度触发可视区域数据计算属性的重新计算。
  startIndex.value = Math.floor(scrollTop / itemHeight)
  // 同步更新数据列表元素translate3d样式y轴的偏移量,确保其始终与视口的最上端对齐
  offsetY.value = scrollTop
}
</script>

<template>
  <el-scrollbar class="vl-container" :height="containerHeight" @scroll="onScroll">
    <div class="vl-wrapper">
      <!--  展示滚动条  -->
      <div
        class="vl-blank"
        :style="{
          height: `${totalCount * itemHeight}px`
        }"
      ></div>
      <!--  数据列表 -->
      <div
        class="vl-data"
        :style="{
          transform: `translate3d(0, ${offsetY}px, 0)`
        }"
      >
        <div class="item" v-for="(item, index) in visibleData" :key="index">Item {{ item.value }}</div>
      </div>
    </div>
  </el-scrollbar>
</template>

<style scoped lang="scss">
.vl-wrapper {
  position: relative;

  .vl-blank {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
  }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值