加载中...

AliveSevenの博客

Vue虚拟列表

发表于: 2023-07-23 |

更新于: 2023-07-23 |

字数统计: 3292 |

阅读量: 0

前言:最近在开发一个通用组件排行榜的时候,需要展示多条数据,数据量虽然不大,但是开发的组件需要嵌入到PC、安卓、IOS多端适配。适配的时候需要处理一下这些数据量,不然会产生性能问题。然后在浏览谷歌的时候就发现虚拟列表这个东西

虚拟列表

  • 虚拟列表是指对列表的 可视区域 进行渲染,对 非可见区域 不渲染或部分渲染,从而极大提高渲染性能的一种技术。

相关库

  • 目前我觉得比较好用的库是**vue-virtual-scroller**
  • 此外还有vue*-*virtual-scroll-list、react-virtualized等

Vue-Virtual-Scroller的使用

安装

powershell 复制代码
npm install --save vue-virtual-scroller@next

yarn add vue-virtual-scroller@next

npm install --save vue-virtual-scroller@next --legacy-peer-deps

在main.js中全局使用

javascript 复制代码
import { createApp } from 'vue';
import VueVirtualScroller from 'vue-virtual-scroller';
import App from './App.vue';

const app = createApp(App)
app.use(VueVirtualScroller)
app.mount('#app')

RecycleScroller组件

  • 使用该组件的时候,需要给定每个item的高度
  • 而DynamicScroller组件,则是不需要知道item的高度,自动计算其值
  • 首先在需要使用的组件中引入 ↓
javascript 复制代码
import { DynamicScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
  • 然后直接使用即可,有几个props需要在使用的时候传入
html 复制代码
<template>
  <div class="reyclerList">
    <RecycleScroller
      style="height: 100%;"
      v-if="list.length > 0"
      :items="list"
      :item-size="50"
      key-field="id"
      :minItemSize="0"
      :buffer="200"
      v-slot="{ item , index }"
    >
      <div>{{ index }} :{{ item.nums }}}</div>
    </RecycleScroller>
  </div>
</template>

<script>
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
export default {
  components: {
    RecycleScroller
  },
  setup() {
    const list = []
    for(let i = 0; i < 10000; i++) {
      list.push({
        id: i,
        nums: `list-nums ${i}`
      })
    }

    return {
      list
    }
  }
}
</script>

<style>
.reyclerList{
  width: 100%;
  height: 600px;
}
</style>
  • 效果
  • 可以看到,使用了RecycleScroller加载1万条数据,只会渲染部分dom,而不会全部加载出来,通过这种方式可以减少dom的加载,极大优化性能

DynamicScroller组件

  • DynamicScroller和RecycleScroller差不多,但是它可以不

相关props传参

  • items: 要在滚动条中显示的总列表。
  • direction (default: 'vertical'): 滚动的方向,列表的方向,有垂直和水平,默认是垂直方向, 'vertical' or 'horizontal'.
  • itemSize: 子列表的高度,默认为null,在RecycleScroller中必须要设置这个
  • minItemSize: 如果子列表的高度(或水平模式下的宽度)未知,则使用最小尺寸。
  • keyField: 默认是是id,列表循环的key值,一般这个也是必传的
  • buffer: 默认是200,到滚动可见区域的边缘以开始渲染更远的项目的像素量。默认是上下200px处的都会进行缓存渲染
  • emitUpdate: 默认是false,表示是否要开启更新模式,官方描述:触发一个 'update' 时间,一般会配合钩子函数update一起使用

相关Events,钩子函数

  • update (startIndex, endIndex, visibleStartIndex, visibleEndIndex): 每次滚动的时候,当可使区域发生变化,触发该钩子函数的方法,仅当props——emitUpdate 为true的时候生效
  • scroll-start: 当第一个item渲染完的时候触发
  • scroll-end: 当最后的一个item渲染完的时候触发

插槽slot

  • item: 可视区域的item
  • index: item的下标
  • active: 可视活动状态下的item

虚拟列表的原理

  • 这里参考了掘金大佬的图,可以很好的解释了虚拟列表的原理
  • 简单来说就是在滚动的时候,让上面和下面的item通过transform向上平移,这样做就可以只渲染少量的dom,减少不必要真实dom的渲染。
  • 监听滚动
  • 需要知道item的高度,每次滚动对每个item进行transform计算
  • 根据滚动的距离和item的高度,计算出startIndex
  • 再根据startIndex和可视区高度计算出endIndex
  • 滚动时候,计算出可视区列表的偏移距离 startOffset,再重新计算startIndexendIndex

手写虚拟列表

...待更

AliveSeven
一个有趣的博客
文章
0
标签
0
分类
0
目录
©2021 - 2025 By AliveSeven
欢迎来到我的博客,谢谢你能在茫茫人海中发现我