×

Vue3 虚拟滚动 的终局方案!V3 发布!

独孤求败 独孤求败 发表于2026-04-24 09:17:16 浏览39 评论0

抢沙发发表评论

在 Vue 生态里,「虚拟列表」这个话题其实早就被讲烂了。

你随便一搜:

Vue 虚拟列表 / Virtual List

出来一堆库。

但现实是——

真正能在 Vue3 项目里稳定跑起来的,没几个。

很多库的问题是:

  • 还停留在 Vue2
  • 强行兼容 Vue3,但实现老旧
  • 一上手就报错(props / slot / 渲染异常
  • 或者性能和体验都不太理想

🚀 转折点:尤雨溪推荐 + v3 发布

最近,Vue 作者尤雨溪推荐了一个库:vue-virtual-scroller

图片

更关键的是:它刚刚发布了 v3.0.0

这次版本升级的意义不只是“支持 Vue3”,而是:

  • ✅ 基于 Vue 3 + Composition API 重构
  • ✅ 架构升级(Headless + Composable)
  • ✅ 性能进一步优化
  • ✅ 支持更多复杂场景(比如 table)

这是目前 Vue3 生态里,最成熟、最工程化的虚拟列表方案之一。

问题本质:为什么大列表会卡?

在聊库之前,先把问题本质搞清楚。

❌ 传统写法

<div v-for="item in list" :key="item.id">
  {{ item.text }}
</div>

如果 list.length = 10000

会发生什么?

DOM 数量爆炸

浏览器需要维护:

  • 10000 个 DOM 节点
  • 每个节点的布局信息
  • 每次滚动都参与计算

滚动性能下降

滚动会触发:

  • layout(重排)
  • paint(重绘)
  • composite(合成)

DOM 越多,成本越高

内存占用过高

每个节点都占用:

  • JS 内存
  • DOM 结构
  • 样式缓存

大致总结就是:性能瓶颈不在数据,而在 DOM。

vue-virtual-scroller 的核心思路

图片

核心理念非常简单,但实现不简单:

只渲染“用户看得见的那一部分”

举个例子

假设:

  • 每个 item 高度:50px
  • 可视区域:500px
  • 数据量:10000

实际只需要渲染:

500 / 50 = 10 个元素

加上 buffer

最多也就几十个 DOM

vue-virtual-scroller 的优势 & 核心能力

相比普通虚拟列表库,它的优势主要在“工程能力”。

1. 极致性能

  • DOM 数量从 O(n) → O(1)
  • 滚动接近 60fps
  • 内存占用显著降低

2. DOM 复用(Recycling)

不是简单的“删除再创建”,而是:

复用已有 DOM 节点

滚动时:

  • 不创建新节点
  • 只更新内容

极大降低 GC 和重排成本

3. 支持动态高度

通过:

  • 自动测量 DOM
  • 缓存高度
  • 动态计算 offset

可以支持复杂列表(聊天、卡片流等)

4. 高度可扩展

v3 之后:

  • 支持 headless 模式
  • UI 和逻辑解耦
  • 可自定义渲染结构

5. 支持复杂结构(重点)

  • table
  • grid
  • 嵌套列表

这是很多库做不到的

关键实现机制(核心原理)

vue-virtual-scroller 的性能来源,不是一个点,而是多个机制叠加。

可视窗口计算

核心问题

当前应该渲染哪些 item

固定高度

index = Math.floor(scrollTop / itemHeight)

然后:

start = index - buffer
end = index + visibleCount + buffer

偏移渲染(translate

结构大致是:

<div style="height: totalHeight">
  <div style="transform: translateY(offset)">
    <!-- 渲染少量元素 -->
  </div>
</div>

两个关键点:

  • 外层:撑开滚动条
  • 内层:控制渲染位置
DOM 复用(最关键)

滚动时:

  • ❌ 销毁 + 创建
  • ✅ 复用 + 更新

例如:

显示 0~10

显示 1~11

实际:

  • 第 0 个节点 → 变成第 11 个数据

动态高度处理

对于不等高列表:

  • 记录每个 item 高度
  • 维护 offset 表
  • 使用二分查找定位 index

这部分是实现难点,也是它比普通库强的地方

如何快速使用

📦 安装

npm install vue-virtual-scroller

🧩 基本使用

<RecycleScroller
  :items="list"
  :item-size="50"
  key-field="id"
  v-slot="{ item }"
>

  <div>{{ item.text }}</div>
</RecycleScroller>
核心参数说明:

参数
说明
items
数据源
item-size
每项高度
key-field
key 字段

三种模式(核心组件)

RecycleScroller(推荐)

场景:

  • 固定高度
  • 高性能要求

特点:

  • 实现最简单
  • 性能最好

DynamicScroller

场景:

  • 不固定高度

特点:

  • 自动计算高度
  • 更灵活

DynamicScrollerItem

作用:

  • 配合 DynamicScroller 使用
  • 负责上报高度

v3 的关键升级(重点)

1. 完全基于 Vue3 重构

  • 使用 Composition API
  • 更清晰的状态管理
  • 更适合复杂逻辑拆分

2. Headless 架构

核心思想:

逻辑和 UI 解耦

以前:

  • 组件 = UI + 逻辑

现在:

  • composable = 逻辑
  • UI 自己实现

Table 支持(非常关键)

v2 痛点:

  • table 无法虚拟滚动
  • 需要 hack

v3

  • 原生支持 <table>
  • 不破坏语义结构

4. API 更灵活

例如:

keyField: item => item.id

支持函数

5. 性能优化

  • 更少 re-render
  • 更平滑滚动
  • 更智能缓存

写在最后

如果你项目里有:

  • 万级列表
  • 表格性能问题
  • 滚动卡顿

强烈推荐 vue-virtual-scroller v3

  • 真正适配 Vue3
  • 架构现代(Composition API)
  • 性能成熟稳定
  • 支持复杂场景

它不仅是一个组件库,而是一个“虚拟列表底层能力库”。

  • 官方地址https://vue-virtual-scroller.netlify.app/
  • Github 地址https://github.com/Akryum/vue-virtual-scroller


群贤毕至

访客