VirtualList 虚拟列表
只渲染可视窗口内的项,支持定高与动态高度两种模式(动态模式按预计算偏移 + 二分查找定位)。
定高
定高
第 0 项 · 项目 1
第 1 项 · 项目 2
第 2 项 · 项目 3
第 3 项 · 项目 4
vue
<script setup lang="ts">
const listData = Array.from({ length: 1000 }, (_, i) => `项目 ${i + 1}`)
</script>
<template>
<LhVirtualList :data="listData" :height="200" :item-height="40">
<template #default="{ item, index }">
<div>第 {{ index }} 项 · {{ item }}</div>
</template>
</LhVirtualList>
</template>vue
<script>
export default {
data() {
return {
listData: Array.from({ length: 1000 }, (_, i) => `项目 ${i + 1}`),
}
},
}
</script>
<template>
<LhVirtualList :data="listData" :height="200" :item-height="40">
<template #default="{ item, index }">
<div>第 {{ index }} 项 · {{ item }}</div>
</template>
</LhVirtualList>
</template>动态高度
itemSize 返回每项高度(可基于测量结果动态返回)。
动态高度
项目 1
项目 2
项目 3
vue
<script setup>
const dynamicSize = (index) => (index % 3 === 0 ? 56 : 36)
</script>
<template>
<LhVirtualList :data="listData" :height="200" :item-size="dynamicSize">
<template #default="{ item, index }">{{ item }}</template>
</LhVirtualList>
</template>vue
<script>
export default {
data() {
return {
listData: Array.from({ length: 1000 }, (_, i) => `项目 ${i + 1}`),
}
},
methods: {
dynamicSize(index) {
return index % 3 === 0 ? 56 : 36
},
},
}
</script>
<template>
<LhVirtualList :data="listData" :height="200" :item-size="dynamicSize">
<template #default="{ item, index }">{{ item }}</template>
</LhVirtualList>
</template>预渲染缓冲
overscan 指定可视窗口外上下各预渲染多少行,减少快速滚动时的白屏。
overscan
第 0 项 · 项目 1
第 1 项 · 项目 2
第 2 项 · 项目 3
第 3 项 · 项目 4
第 4 项 · 项目 5
第 5 项 · 项目 6
第 6 项 · 项目 7
第 7 项 · 项目 8
第 8 项 · 项目 9
第 9 项 · 项目 10
第 10 项 · 项目 11
第 11 项 · 项目 12
第 12 项 · 项目 13
第 13 项 · 项目 14
第 14 项 · 项目 15
第 15 项 · 项目 16
vue
<script setup lang="ts">
const listData = Array.from({ length: 1000 }, (_, i) => `项目 ${i + 1}`)
</script>
<template>
<LhVirtualList
:data="listData"
:item-height="40"
:height="200"
:overscan="8"
/>
</template>vue
<script>
export default {
data() {
return {
listData: Array.from({ length: 1000 }, (_, i) => `项目 ${i + 1}`),
}
},
}
</script>
<template>
<LhVirtualList
:data="listData"
:item-height="40"
:height="200"
:overscan="8"
/>
</template>API
LhVirtualList Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| data | 数据源(项渲染由 default 插槽负责) | any[] | — |
| height | 容器高度(数字为 px) | string | number | — |
| itemHeight | 定高模式的项高 | number | — |
| itemSize | 动态高度模式:由调用方返回每项高度 | (index: number) => number | — |
| overscan | 过扫描项数 | number | LH_VIRTUAL_OVERSCAN |
| sx | sx 快速布局属性 | LhSxProps | — |
插槽:default(作用域 { item, index })。
无障碍
- 容器
overflow: auto可键盘滚动;窗口外的项不在 DOM 中,屏读按需获取(长列表的固有取舍,建议配合搜索/筛选缩小范围) - 若需完整语义表格请用 Table(其虚拟滚动同样由 core 纯函数驱动)
类型定义
本组件对外导出的 TypeScript 类型结构如下(自动提取自 packages/components/virtual-list/src/types.ts 与 @lh-ui/share/core/* 源码,点击各条目展开查看完整定义;属性说明见上方 Props 表):
LhVirtualListProps
ts
export interface LhVirtualListProps {
/** 数据源(项渲染由 default 插槽负责) */
data: any[]
/** 容器高度(数字为 px) */
height: number | string
/** 定高模式的项高(与 itemSize 二选一;提供了 itemSize 时走动态高度) */
itemHeight?: number
/** 动态高度模式:由调用方返回每项高度 */
itemSize?: (index: number) => number
/** 过扫描项数 */
overscan?: number
/** sx 快速布局属性 */
sx?: LhSxProps
}常量
本组件用到的公开常量如下(可在 Props 表的「类型 / 默认值」列点击同名条目跳转至此):
LH_VIRTUAL_ITEM_SIZE (来自 @lh-ui/share/core/virtual-list)
ts
/** 默认估算项高 */
export const LH_VIRTUAL_ITEM_SIZE = 40