Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo
Theme
Mode
Accessibility
Vuetify

Sign in

Sign in with your preferred provider to access your account.

createVirtual

Virtual scrolling composable for efficiently rendering large lists by only rendering visible items.


Intermediate91.8% coverageBlazing FastFeb 18, 2026

Usage

The createVirtual composable efficiently renders large lists by only mounting visible items plus a small overscan buffer. Pass an array of items and configure the item height to get back sliced items, scroll handlers, and positioning values.

0 (rendered) / 10000
<script setup lang="ts">
  import { createVirtual } from '@vuetify/v0'
  import { computed, shallowRef } from 'vue'

  const items = shallowRef(
    Array.from({ length: 10_000 }, (_, i) => ({
      id: i,
      name: `Item ${i + 1}`,
      value: Math.floor(Math.random() * 1000),
    })),
  )

  const virtual = createVirtual(items, { itemHeight: 40 })
  const {
    element,
    items: virtualItems,
    offset,
    size,
    scroll,
    scrollTo,
  } = virtual

  const stats = computed(() => ({
    total: items.value.length,
    rendered: virtualItems.value.length,
  }))

  const jumpTo = shallowRef('')
  function handleJumpTo () {
    const index = Number.parseInt(jumpTo.value) - 1

    if (index < 0 || index > items.value.length) return

    scrollTo(index)
  }

  function addItems () {
    const newItems = Array.from({ length: 100 }, (_, i) => ({
      id: items.value.length + i,
      name: `Item ${items.value.length + i + 1}`,
      value: Math.floor(Math.random() * 1000),
    }))
    items.value = [...items.value, ...newItems]
  }
</script>

<template>
  <div class="flex flex-col gap-3">
    <div class="flex gap-2 items-center text-sm flex-wrap">
      <input
        v-model="jumpTo"
        class="px-2 py-1 border border-divider bg-surface text-on-surface rounded w-24 flex-1 md:flex-none"
        placeholder="Jump to..."
        type="number"
        @keyup.enter="handleJumpTo"
      >

      <button class="px-3 py-1 border border-divider rounded hover:bg-surface-tint" @click="handleJumpTo">
        Jump
      </button>

      <button class="px-3 py-1 border border-divider rounded hover:bg-surface-tint" @click="addItems">
        Add 100
      </button>

      <span class="text-on-surface opacity-60 ml-auto">
        {{ stats.rendered }} (rendered) / {{ stats.total }}
      </span>
    </div>

    <div
      ref="element"
      class="h-[300px] overflow-y-auto border border-divider rounded"
      @scroll="scroll"
    >
      <div :style="{ height: `${offset}px` }" />

      <div
        v-for="item in virtualItems"
        :key="item.index"
        class="h-[40px] px-4 flex items-center justify-between border-b border-divider hover:bg-surface-tint"
      >
        <span class="font-mono text-sm text-on-surface">{{ item.raw.name }}</span>
        <span class="text-on-surface opacity-60">{{ item.raw.value }}</span>
      </div>

      <div :style="{ height: `${size}px` }" />
    </div>
  </div>
</template>

Architecture

The rendering pipeline transforms scroll events into visible item ranges:

Virtual Rendering Pipeline

Use controls to zoom and pan. Click outside or press Escape to close.

Virtual Rendering Pipeline

Reactivity

Property/MethodReactiveNotes
elementRef, assign scroll container
itemsComputed, visible items with index
offsetShallowRef, readonly (top spacer height)
sizeShallowRef, readonly (bottom spacer height)
stateShallowRef ('loading' | 'empty' | 'error' | 'ok')
Tip

Source items The items ref passed to createVirtual() is watched for changes. When items change, the virtual scroller updates automatically.

API Reference

The following API details are for the createVirtual composable.

Functions

createVirtual

(items: Ref<readonly T[], readonly T[]>, _options?: VirtualOptions) => VirtualContext<T>

Virtual scrolling composable for efficiently rendering large lists

createVirtualContext

(items: Ref<readonly T[], readonly T[]>, _options?: VirtualContextOptions) => ContextTrinity<VirtualContext<T>>

Creates a virtual scrolling context with dependency injection support.

useVirtual

(namespace?: string) => VirtualContext<T>

Returns the current virtual context from dependency injection.

Options

itemHeight

string | number

The height of the item.

height

string | number

The height of the container.

overscan

number

The number of extra items to render.

direction

VirtualDirection

The direction of the scrolling.

anchor

VirtualAnchor

The anchor of the scrolling.

anchorSmooth

boolean

Whether to smooth the anchor position.

onStartReached

(distance: number) => void | Promise<void>

The callback to call when the start is reached.

onEndReached

(distance: number) => void | Promise<void>

The callback to call when the end is reached.

startThreshold

number

The threshold for the start.

endThreshold

number

The threshold for the end.

momentum

boolean

Whether to enable momentum scrolling.

elastic

boolean

Whether to enable elastic scrolling.

Properties

element

Ref<HTMLElement, HTMLElement>

The element that is being virtualized.

items

ComputedRef<VirtualItem<T>[]>

The items that are being virtualized.

offset

Readonly<ShallowRef<number>>

The offset of the virtualized items.

size

Readonly<ShallowRef<number>>

The size of the virtualized items.

state

ShallowRef<VirtualState>

The state of the virtualized items.

Methods

scrollTo

(index: number, options?: ScrollToOptions) => void

Scroll to an item by index.

scroll

() => void

The scroll event handler.

scrollend

() => void

The scrollend event handler.

resize

(index: number, height: number) => void

Resize an item by index.

reset

() => void

Reset the virtualized items.

Benchmarks

Every operation is profiled across multiple dataset sizes to measure real-world throughput. Each benchmark is assigned a performance tier—good, fast, blazing, or slow—and groups are scored by averaging their individual results so you can spot bottlenecks at a glance. This transparency helps you make informed decisions about which patterns scale for your use case. Learn more in the benchmarks guide.

View benchmark source↗

Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/