VirtualList

虚拟滚动列表底座,渲染大数据量时只渲染视口内的可见行。

设计文档(新窗口打开)

与 Semi Design 的技术差异:Semi 没有独立的 VirtualList 组件,它的虚拟滚动能力由第三方库 react-window(Tree / TreeSelect / Cascader / Select)与 react-virtualized(List 无限长列表)提供,作为内部实现细节,不对外导出。Svelte 生态没有可直接复用的等价库,因此本库自建了这个 headless VirtualList 基座,被 Table / List / TreeSelect / Cascader 等组件复用。它是技术栈差异导致的必要自建,Semi 官网无对应文档页。

代码演示

如何引入

import { VirtualList } from '@chenzy-design/svelte';

基础虚拟列表

通过 data 传入数据、itemSize 指定固定行高,万行数据仅渲染视口内的可见行。

固定行高(1 万行,itemSize=36,仅渲染视口内行)
第 1 行
第 2 行
第 3 行
第 4 行
第 5 行
第 6 行
第 7 行
第 8 行
第 9 行

动态/不定高

itemSize='auto' 时用 ResizeObserver 实测每行真实高度并修正偏移,estimatedItemSize 提供首屏占位估算。

动态/不定高(itemSize='auto',估算 56px,实测后修正偏移)
第 1 条 — 虚拟列表只渲
第 2 条 — 虚拟列表只渲染
第 3 条 — 虚拟列表只渲染视
第 4 条 — 虚拟列表只渲染视口
第 5 条 — 虚拟列表只渲染视口内
第 6 条 — 虚拟列表只渲染视口内的
第 7 条 — 虚拟列表只渲染视口内的行
第 8 条 — 虚拟列表只渲染视口内的行,

滚动到指定项

通过 bind:this 拿到组件实例,命令式调用 scrollToIndex(index, { align }) 滚动到指定行。

#0 — 第 1 行
#1 — 第 2 行
#2 — 第 3 行
#3 — 第 4 行
#4 — 第 5 行
#5 — 第 6 行
#6 — 第 7 行
#7 — 第 8 行
#8 — 第 9 行

横向虚拟化

horizontal 沿 x 轴排列,itemSize 作列宽(仅支持 fixed 定宽)。

横向虚拟化(horizontal,列宽 80px,1 万列只渲染视口列)
1
2
3

自定义项渲染

renderItem 内可组合任意富结构(Tag、图标等),只要保证行高与 itemSize 一致。

自定义项渲染(renderItem 内组合 Tag + 富结构,固定行高 52px)
P0
任务 1 已完成
P1
任务 2 进行中
P2
任务 3 进行中
P0
任务 4 进行中
P1
任务 5 已完成
P2
任务 6 进行中
P0
任务 7 进行中
P1
任务 8 进行中

API 参考

VirtualList

属性说明类型默认值
class根节点自定义类名string-
data列表数据源T[][]
estimatedItemSize动态模式(itemSize=‘auto’)下的初始估算行高(px),用于首屏占位与总高估算number40
getKey每项的稳定 key 生成函数(item: T, index: number) => string | number(_, index) => index
height视口主轴尺寸(vertical 为高度、horizontal 为宽度);数字按 px,字符串用 ResizeObserver 测量number | string400
horizontal横向虚拟化:沿 x 轴排列、读/写 scrollLeftbooleanfalse
itemSize固定行高/列宽(px);传 auto 启用动态不定高测量(horizontal 暂不支持 dynamic)number | auto40
overscan视口上下额外预渲染的行数number3
renderItem渲染每一项的模板Snippet<[item, index]>-
scrollTarget滚动源:self 内部容器自身滚动 / window 用窗口滚动(适合整页长列表,仅 vertical)self | windowself

方法

通过 bind:this 拿到组件实例后可命令式调用:

方法说明
scrollToIndex(index, options?)滚动到指定项;options.align 支持 start / center / end

无障碍

  • VirtualList 本身是透明容器,不添加额外 role;具体 role(list/grid/listbox 等)由上层调用方传入,确保语义由业务层决定。
  • 每行渲染时注入 aria-setsize(数据总量)和 aria-posinset(当前行在全列表中的位置),使屏幕阅读器可感知「第 N 条,共 M 条」。
  • 当前聚焦的行不会被虚拟回收,确保键盘导航时焦点不丢失。
  • 滚动时以 rAF 节流控制 ARIA 属性更新频率,避免辅助技术被频繁的属性变更淹没。

设计变量

变量
默认值
用法
--cd-virtual-list-bg var(--cd-color-bg-0) 虚拟列表容器背景色
--cd-virtual-list-scrollbar var(--cd-color-fill-1) 虚拟列表滚动条颜色
显示第 1 条-第 2 条,共 2 条
  • 1