Выпадающие списки CdsSelect и CdsAutocomplete, как и дерево CdsTree, уже виртуализируют свои элементы — оборачивать их не нужно. Короткий список — до пары сотен строк — рендерите обычным CdsList: виртуализация выигрыша не даст.
Вариации
Фиксированная высота
Проп height задаёт высоту области просмотра — внутри неё появляется прокрутка. Если все строки одной высоты, укажите item-height: компонент не будет измерять каждую строку, а позиции и полоса прокрутки будут точными с первого рендера.
Динамическая высота
Без item-height компонент измеряет строки автоматически — подходит для контента переменной длины: комментариев, сообщений, описаний. Высоты уточняются по мере прокрутки, поэтому полоса прокрутки может слегка сдвигаться.
Безрамочный режим
Проп renderless убирает собственный скролл-контейнер: компонент слушает прокрутку ближайшего скроллируемого родителя, а строки рендерит без обёрток. Слот дополнительно получает itemRef — привяжите его к корневому узлу строки, чтобы компонент знал её высоту. Так список встраивается в уже существующую прокрутку — панели или всей страницы. Скроллируемому родителю задайте position: relative — от него компонент отсчитывает позиции строк.
Рекомендации
Сценарии использования
Поиск по каталогу
Передавайте в items уже отфильтрованный массив: computed пересчитывает записи по вводу, а компонент подхватывает новый список сам. item-key="id" привязывает строки к записям, а не к позициям в массиве — при фильтрации строки не перепутаются.
Быстрый переход по журналу
Компонент отдаёт метод scrollToIndex — получите его через ref и прокручивайте список программно. Кнопки месяцев считают индекс первой операции месяца; с фиксированным item-height переход попадает точно в нужную строку.
Выбор в длинном списке
Строки за пределами экрана не существуют в DOM, поэтому состояние выбора храните в данных, а не в самих строках. В демо отмеченные id лежат в Set: чекбокс строки читает его и меняет по клику — выбор переживает любую прокрутку.
API
CdsVirtualScroll
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
height | string | number | undefined | — | Высота компонента |
itemHeight | string | number | undefined | null | Высота одного элемента в пикселях. Если не задана — высота измеряется автоматически. |
itemKey | SelectItemKey | null | Ключ элемента для идентификации (имя поля, путь или функция). По умолчанию используется индекс. |
items | readonly unknown[] | undefined | [] | Массив элементов, которые отрисовываются виртуальным скроллом. |
maxHeight | string | number | undefined | — | Максимальная высота компонента |
maxWidth | string | number | undefined | — | Максимальная ширина компонента |
minHeight | string | number | undefined | — | Минимальная высота компонента |
minWidth | string | number | undefined | — | Минимальная ширина компонента |
renderless | boolean | undefined | — | Безрамочный режим: компонент не создаёт собственный скролл-контейнер, а использует ближайший скроллируемый родитель. |
width | string | number | undefined | — | Ширина компонента |
Слоты
| Имя | Тип | Описание |
|---|---|---|
default | CdsVirtualScrollSlot<any> & { itemRef?: TemplateRef | undefined; } | Содержимое одного элемента списка. В режиме renderless дополнительно получает itemRef. |
Exposed
| Имя | Тип | Описание |
|---|---|---|
calculateVisibleItems | () => void | Пересчитывает окно видимых элементов — нужно после изменения их высоты вне цикла обновления. |
scrollToIndex | (index: number) => void | Прокручивает список к элементу с указанным индексом. |
CdsVirtualScrollItem
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
renderless | boolean | undefined | — | Безрамочный режим: элемент рендерит только содержимое слота без обёртки. |
События
| Имя | Тип | Описание |
|---|---|---|
update:height | [height: number] | Сообщает виртуальному списку об изменении высоты элемента. |
Слоты
| Имя | Тип | Описание |
|---|---|---|
default | { itemRef: TemplateRef; } | Содержимое элемента. В режиме renderless получает itemRef для измерения высоты. |