Виртуальный список
Отрисовывает только элементы, попадающие в видимое окно; поддерживает два режима — фиксированная высота и динамическая высота (в динамическом режиме позиционирование выполняется по предварительно вычисленным смещениям + двоичному поиску).
Фиксированная высота
<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><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 возвращает высоту каждого элемента (может возвращать значение на основе результатов измерений).
<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><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 указывает, сколько строк предварительно отрисовывается с каждой стороны (сверху и снизу) за пределами видимого окна, что уменьшает появление пустых областей при быстрой прокрутке.
<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><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 (scoped-слот { item, index }).
Доступность
- Контейнер с
overflow: autoпрокручивается с клавиатуры; элементы за пределами окна отсутствуют в DOM, экранный диктор получает их по необходимости (неизбежный компромисс для длинных списков; рекомендуется дополнять поиском/фильтрацией для сужения области) - Если нужна полноценная семантическая таблица, используйте Table (его виртуальная прокрутка также управляется чистыми функциями core)
Типы
Экспортируемые компонентом структуры TypeScript (автоматически извлечено из packages/components/virtual-list/src/types.ts и исходников @lh-ui/share/core/*; раскройте каждый раздел, чтобы увидеть полное определение; описания свойств — в таблице Props выше):
LhVirtualListProps
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)
/** Высота элемента по умолчанию (оценка) */
export const LH_VIRTUAL_ITEM_SIZE = 40