Skip to content
API 风格:

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過掃描項數numberLH_VIRTUAL_OVERSCAN
sxsx 快速版面配置屬性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