Skyroc UI
数据展示

Virtualizer

用于高效渲染大列表和大网格的虚拟滚动组件

Virtualizer 基于 @tanstack/react-virtual 封装,提供 VirtualListVirtualGrid 两个常用组件,并 re-export useVirtualizeruseWindowVirtualizer 供更底层的自定义场景使用。

import { VirtualList, VirtualGrid, useVirtualizer, useWindowVirtualizer } from '@skyroc/web-ui';

何时使用

  • 列表或网格数据量很大,直接渲染全部 DOM 会影响性能。
  • 每一项高度或宽度可以预估,或可以通过动态测量处理。
  • 需要保留滚动容器、滚动位置、滚动到指定索引等底层控制能力。
  • 数据量很小或内容高度不可预测且频繁变化时,普通列表通常更简单。

基础列表

VirtualList 只渲染可视区域附近的项目。垂直列表需要设置 heightitemSize;横向列表可以设置 horizontalwidthitemSize

Preview
Code
Loading...
<VirtualList data={items} height={300} itemSize={40} renderItem={({ item, index }) => <div>{item.name}</div>} />

可变尺寸

itemSize 可以是函数,用于根据索引返回不同的预估尺寸。适合内容高度存在规律差异,但不需要动态测量的场景。

Preview
Code
Loading...
<VirtualList
  data={items}
  height={300}
  itemSize={index => items[index].height}
  keyExtractor="id"
  renderItem={({ item }) => <div>{item.content}</div>}
/>

虚拟网格

VirtualGrid 同时对行和列进行虚拟化。通过 columns 指定总列数,rowHeightcolumnWidth 提供行高与列宽预估。

Preview
Code
Loading...
<VirtualGrid
  data={items}
  columns={10}
  rowHeight={60}
  columnWidth={100}
  height={300}
  renderCell={(item, rowIndex, colIndex) => <div>{item.content}</div>}
/>

实例控制

VirtualListref 会暴露底层 virtualizer 实例和滚动容器引用,可用于滚动到指定索引、读取可见项等控制场景。

Preview
Code
Loading...
const virtualizerRef = useRef<VirtualizerList>(null);

virtualizerRef.current?.scrollToIndex(5000, { align: 'center' });

动态测量

设置 dynamic 后,VirtualList 会把渲染项挂到 measureElement 上,让 TanStack Virtual 在实际 DOM 渲染后测量尺寸。动态测量适合真实高度难以准确预估的内容。

<VirtualList dynamic data={items} height={300} itemSize={48} renderItem={({ item }) => <div>{item.description}</div>} />

API

VirtualList

一维虚拟列表组件,支持垂直、横向、固定尺寸、函数式预估尺寸和动态测量。

属性说明类型默认值
data*需要虚拟化渲染的数据列表item[]-
itemSize*项目预估尺寸;垂直列表表示高度,横向列表表示宽度number | (index: number) => number-
renderItem*项目渲染函数(props: VirtualListItem) => ReactNode-
height滚动容器高度number | string-
width滚动容器宽度number | string-
horizontal是否启用横向虚拟滚动booleanfalse
dynamic是否启用动态尺寸测量booleanfalse
keyExtractor从数据项中提取稳定 keyproperty key | (item, index) => string-
onScroll滚动偏移变化时触发(offset: number) => void-
className滚动容器自定义 classClassValue-
classNames各 slot 的自定义 class(root / inner)VirtualizerClassNames-
containerProps传递给滚动容器 div 的额外属性container div props-
ref虚拟列表实例引用VirtualizerList-

VirtualGrid

二维虚拟网格组件,同时虚拟化行与列。

属性说明类型默认值
data*需要虚拟化渲染的数据列表item[]-
columns*总列数number-
rowHeight*行高预估值或函数number | (rowIndex: number) => number-
columnWidth*列宽预估值或函数number | (colIndex: number) => number-
renderCell*单元格渲染函数(item, rowIndex: number, colIndex: number) => ReactNode-
height滚动容器高度number | string-
width滚动容器宽度number | string-
columnProps传递给列 virtualizer 的额外配置VirtualizerBaseOptions-
keyExtractor从数据项中提取稳定 keyproperty key | (item, index) => string-
onScroll纵向滚动偏移变化时触发(offset: number) => void-
className滚动容器自定义 classClassValue-
classNames各 slot 的自定义 class(root / inner)VirtualizerClassNames-
ref虚拟网格实例引用VirtualizerGrid-

Hooks

useVirtualizeruseWindowVirtualizer 直接从 @tanstack/react-virtual re-export,适合完全自定义 DOM 结构或窗口级虚拟滚动场景。

const rowVirtualizer = useVirtualizer({
  count: rows.length,
  estimateSize: () => 40,
  getScrollElement: () => parentRef.current
});

类型

VirtualizerClassNames

Virtualizer 各 slot 的自定义 class。

字段类型说明
rootClassValue滚动容器 class。
innerClassValue内部占位层 class。

VirtualListItem

VirtualList renderItem 函数接收的参数。

字段类型说明
indexnumber数据项索引。
itemitem data当前数据项。
virtualItemvirtual item objectTanStack Virtual 当前虚拟项信息。
virtualizervirtualizer instance当前列表 virtualizer 实例。

VirtualizerBaseOptions

传递给 TanStack Virtual 的基础配置类型。

字段类型说明
overscannumber可视区域外额外渲染的项目数量。
horizontalboolean是否横向虚拟滚动。
paddingStartnumber开始位置内边距。
paddingEndnumber结束位置内边距。
gapnumber项目间距。
onChange(instance, sync) => voidvirtualizer 状态变化回调。

VirtualizerProps

VirtualList 和 VirtualGrid 共享的基础属性。

字段类型说明
dataitem[]数据列表。
heightnumber | string滚动容器高度。
widthnumber | string滚动容器宽度。
keyExtractorproperty key | (item, index) => string稳定 key 提取函数。
onScroll(offset: number) => void滚动偏移变化回调。
classNameClassValue滚动容器 class。
classNamesVirtualizerClassNames各 slot 的自定义 class。

VirtualListProps

VirtualList 组件属性。

字段类型说明
dataitem[]数据列表。
itemSizenumber | (index: number) => number项目预估尺寸。
renderItem(props: VirtualListItem) => ReactNode项目渲染函数。
dynamicboolean是否启用动态测量。
horizontalboolean是否横向滚动。
refVirtualizerList实例引用。
...basePropsVirtualizerProps共享基础属性。

VirtualGridProps

VirtualGrid 组件属性。

字段类型说明
dataitem[]数据列表。
columnsnumber总列数。
rowHeightnumber | (rowIndex: number) => number行高预估。
columnWidthnumber | (colIndex: number) => number列宽预估。
renderCell(item, rowIndex: number, colIndex: number) => ReactNode单元格渲染函数。
columnPropsVirtualizerBaseOptions列 virtualizer 配置。
refVirtualizerGrid实例引用。
...basePropsVirtualizerProps共享基础属性。

VirtualizerList

VirtualList 暴露的实例引用。

字段类型说明
containerRefdiv element滚动容器元素。
scrollToIndex(index: number, options?) => void滚动到指定索引。
scrollToOffset(offset: number, options?) => void滚动到指定偏移。
getVirtualItems() => virtual item object[]获取当前虚拟项列表。
getTotalSize() => number获取总占位尺寸。

VirtualizerGrid

VirtualGrid 暴露的实例引用。

字段类型说明
containerRefdiv element滚动容器元素。
rowVirtualizerVirtualizerList行 virtualizer 实例。
columnVirtualizerVirtualizerList列 virtualizer 实例。
scrollToIndex(index: number, options?) => void滚动到指定行索引。
getVirtualItems() => virtual item object[]获取当前虚拟行列表。

ClassValue

CSS 类名类型

string | null | undefined | Record<string, boolean> | ClassValue[]

On this page