> Leaf UI 0.8.1 · Package: @ifhover/leaf-ui · Source: 435bab23cad7d343653d9b63b049c0b0601eeefb
> Browser documentation: https://ifhover.github.io/leaf-ui/components/virtual-list.html

> For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/llms-full.txt.

# VirtualList 虚拟列表

流畅浏览大量列表内容。

## 基本用法


- 项目 1
- 项目 2
- 项目 3
- 项目 4
- 项目 5
- 项目 6
- 项目 7
- 项目 8
- 项目 9
- 项目 10
- 项目 11

basic.tsx

复制代码

```tsx lineNumbers file="../../src/examples/virtual-list/basic.tsx"
import { VirtualList } from '@ifhover/leaf-ui';

import { useState } from 'react';

export function VirtualListBasic() {
  const [items] = useState(() =>
    Array.from({ length: 10000 }, (_, index) => ({
      id: String(index),
      name: `项目 ${index + 1}`,
    })),
  );
  return (
    <VirtualList
      items={items}
      itemKey={(item) => item.id}
      height={240}
      estimateSize={44}
      renderItem={(item) => <div style={{ padding: '12px 16px' }}>{item.name}</div>}
    />
  );
}
```

展开代码

## 更多用法


跳至第 501 项

- **#0**

长度不同的内容。 


- **#1**

长度不同的内容。 长度不同的内容。 


- **#2**

长度不同的内容。 长度不同的内容。 长度不同的内容。 


- **#3**

长度不同的内容。 


- **#4**

长度不同的内容。 长度不同的内容。 


- **#5**

长度不同的内容。 长度不同的内容。 长度不同的内容。 


- **#6**

长度不同的内容。 


- **#7**

长度不同的内容。 长度不同的内容。 


- **#8**

长度不同的内容。 长度不同的内容。 长度不同的内容。 



advanced.tsx

复制代码

```tsx lineNumbers file="../../src/examples/virtual-list/advanced.tsx"
import { Button, Space, VirtualList } from '@ifhover/leaf-ui';

import { useRef, useState } from 'react';

export function VirtualListDynamic() {
  const list = useRef<import('@ifhover/leaf-ui').VirtualListHandle>(null);
  const [items] = useState(() =>
    Array.from({ length: 1000 }, (_, index) => ({
      id: String(index),
      text: '长度不同的内容。 '.repeat((index % 3) + 1),
    })),
  );
  return (
    <Space direction="vertical" align="stretch">
      <Button variant="outline" onClick={() => list.current?.scrollToIndex(500, 'start')}>
        跳至第 501 项
      </Button>
      <VirtualList
        ref={list}
        items={items}
        itemKey={(item) => item.id}
        height={220}
        estimateSize={60}
        renderItem={(item) => (
          <div style={{ padding: 16 }}>
            <strong>#{item.id}</strong>
            <p style={{ margin: '4px 0' }}>{item.text}</p>
          </div>
        )}
      />
    </Space>
  );
}
```

展开代码

## 使用说明

itemKey 必须稳定。estimateSize 用于初始估计，之后自动测量行高。SSR 输出确定的初始窗口，挂载后根据容器调整。

## 类型

组装数据、定义回调和使用 ref 时，可以导入这些类型。

```ts
import type { VirtualListHandle, VirtualListProps } from '@ifhover/leaf-ui';
```

## VirtualListHandle API

| 属性               | 类型                                                                        | 默认值 | 说明     |
| ---------------- | ------------------------------------------------------------------------- | --- | ------ |
| `element`        | `HTMLDivElement \| null`                                                  | 必填  | 滚动容器元素 |
| `scrollToIndex`  | `(index: number, align?: 'auto' \| 'start' \| 'center' \| 'end') => void` | 必填  | 滚动至项目  |
| `scrollToOffset` | `(offset: number) => void`                                                | 必填  | 滚动至偏移量 |

## VirtualListProps API

| 属性             | 类型                                               | 默认值     | 说明                |
| -------------- | ------------------------------------------------ | ------- | ----------------- |
| `items`        | `readonly T[]`                                   | 必填      | 数据项目，保持 key 唯一且稳定 |
| `itemKey`      | `(item: T, index: number) => Key`                | 必填      | 提取稳定的项目标识         |
| `renderItem`   | `(item: T, index: number) => ReactNode`          | 必填      | 自定义项目内容           |
| `height`       | `number`                                         | `320`   | 高度，数字按像素计算        |
| `estimateSize` | `number \| ((item: T, index: number) => number)` | `40`    | 预估项目尺寸，挂载后测量实际尺寸  |
| `overscan`     | `number`                                         | `5`     | 可见区域外预渲染数量        |
| `emptyContent` | `ReactNode`                                      | —       | 空列表内容             |
| `horizontal`   | `boolean`                                        | `false` | 横向虚拟列表            |
