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