VirtualScrollbar
Темизируемый кастомный оверлей скроллбара. Отделён от useVirtualScroll — он работает с элементом прокрутки, предоставляемым любым из компонентов выше (через getScrollElement()), либо с любым прокручиваемым элементом, переданным напрямую. Рендерит трек + перетаскиваемый ползунок, размер и позиция которого вычисляются из scrollHeight/clientHeight/scrollTop, перетаскивание — через pointer-события.
Ползунок — полноценный виджет role="scrollbar": aria-orientation/aria-valuemin/aria-valuemax/aria-valuenow отражают текущую позицию прокрутки, и им можно управлять с клавиатуры — стрелки сдвигают позицию, Home/End прыгают к началу/концу, PageUp/PageDown — на размер вьюпорта.
Пропы
target
() => HTMLElement | null
Возвращает элемент прокрутки для синхронизации.
orientation
'vertical' | 'horizontal' · по умолчанию: 'vertical'
Ось прокрутки для отслеживания.
minThumbSize
number · по умолчанию: 24
Минимальный размер ползунка в px, чтобы огромный список не сжимал его до неухватываемой полоски.
Публичный API
refresh()
Принудительно переподключиться и пересчитать состояние против текущего target() — полезно после ручной замены DOM, которую собственные ResizeObserver/слушатели прокрутки компонента иначе не заметят.
scrollbarRef.value?.refresh()CSS custom properties
--vvsk-scrollbar-size
По умолчанию: 10px
Толщина трека/ползунка.
--vvsk-scrollbar-track
По умолчанию: transparent
Фон трека.
--vvsk-scrollbar-thumb
По умолчанию: rgb(255 255 255 / 25%)
Фон ползунка.
--vvsk-scrollbar-thumb-hover
По умолчанию: rgb(255 255 255 / 40%)
Фон ползунка при наведении/перетаскивании.
Пример
<script setup lang="ts">
import { ref } from 'vue'
import { VirtualList, VirtualScrollbar } from 'vue-virtual-scroller-kit'
import type { VirtualListExpose } from 'vue-virtual-scroller-kit'
const listRef = ref<VirtualListExpose | null>(null)
const items = Array.from({ length: 10_000 }, (_, i) => ({ id: i, text: `Row ${i + 1}` }))
</script>
<template>
<div style="position: relative; display: flex; height: 500px">
<VirtualList
ref="listRef"
:items="items"
:estimated-item-size="48"
class="vvsk-scrollbar-hidden"
style="flex: 1"
>
<template #default="{ item }">
<div style="padding: 12px 16px; border-bottom: 1px solid #eee">{{ item.text }}</div>
</template>
</VirtualList>
<VirtualScrollbar :target="() => listRef?.getScrollElement() ?? null" />
</div>
</template>Скрыть нативный скроллбар на связанном контейнере при использовании VirtualScrollbar (опционально — они могут сосуществовать, если нужны оба):
.vvsk-scrollbar-hidden {
scrollbar-width: none; /* Firefox */
}
.vvsk-scrollbar-hidden::-webkit-scrollbar {
display: none; /* Chrome, Safari, Edge */
}