Virtual Scroller

Efficiently renders large responsive grids by mounting only the visible rows.

Installation

npx alixan-ui-nuxt add virtual-scroller

Usage

Product 1

990 ₸

Product 2

1,000 ₸

Product 3

1,010 ₸

Product 4

1,020 ₸

Product 5

1,030 ₸

Product 6

1,040 ₸

Product 7

1,050 ₸

Product 8

1,060 ₸

Product 9

1,070 ₸

Product 10

1,080 ₸

Product 11

1,090 ₸

Product 12

1,100 ₸

<script setup lang="ts">
import VirtualScroller from '@/components/ui/virtual-scroller/VirtualScroller.vue'

const products = Array.from({ length: 1000 }, (_, index) => ({
  id: index + 1,
  name: `Product ${index + 1}`,
  price: 990 + index * 10,
}))
</script>

<template>
  <VirtualScroller
    :items="products"
    item-key="id"
    :row-height="156"
    :min-column-width="180"
    class="h-96"
    grid-class="grid grid-cols-2 gap-3 min-[600px]:grid-cols-[repeat(auto-fill,minmax(180px,1fr))]"
  >
    <template #default="{ item }">
      <article class="h-36 rounded-2xl border bg-card p-4">
        <p class="font-medium">{{ item.name }}</p>
        <p class="mt-2 text-sm text-muted-foreground">
          {{ item.price.toLocaleString() }} ₸
        </p>
      </article>
    </template>
  </VirtualScroller>
</template>

API Reference

PropTypeDefaultDescription
itemsT[]-Items rendered by the virtual grid.
itemKeykeyof T | (item, index) => string | number-Stable item key or a function that returns one.
rowHeightnumber312Fixed height of one grid row in pixels, including its gap.
minColumnWidthnumber240Minimum column width used to calculate the responsive column count.
gapnumber12Gap between rows and columns in pixels.
overscanRowsnumber3Extra rows rendered above and below the viewport.
gridClassstringresponsive gridClasses applied to the positioned grid of visible items.
PropDescription
defaultRenders a visible item and exposes its source index.
headerOptional content that scrolls before the virtualized grid.