Skip to content
API 风格:

Виртуальный список ​

Отрисовывает только элементы, попадающие в видимое окно; поддерживает два режима — фиксированная высота и динамическая высота (в динамическом режиме позиционирование выполняется по предварительно вычисленным смещениям + двоичному поиску).

Фиксированная высота ​

Фиксированная высота
Элемент 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
sxСвойства быстрой раскладки sxLhSxProps—

Слоты: default (scoped-слот { 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
  /** Высота элемента в режиме фиксированной высоты (выбирается одно из двух: itemHeight или 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

Красота традиций — основа кода