TanStack logo

Skill

with-tanstack-virtual

virtualize Vue table rows and columns

Covers Performance Vue UI Components TanStack

Description

Virtualize Vue Table final row or column models with reactive counts and scroll targets, stable keys, measurement, spacer geometry, sticky CSS, grid/flex widths, and infinite server data.

SKILL.md

This skill builds on @tanstack/table-core#core, getting-started, and table-state. Virtual consumes final Table models; it is not registered in tableFeatures.

Setup

import { computed, ref } from 'vue'
import { useVirtualizer } from '@tanstack/vue-virtual'

const scrollElement = ref<HTMLElement | null>(null)
const rows = computed(() => table.getRowModel().rows)
const rowVirtualizer = useVirtualizer(
  computed(() => ({
    count: rows.value.length,
    getScrollElement: () => scrollElement.value,
    estimateSize: () => 34,
    getItemKey: (index) => rows.value[index]!.id,
    overscan: 5,
  })),
)
const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems())
const totalSize = computed(() => rowVirtualizer.value.getTotalSize())

Core Patterns

Derive from current visible models

Rows come from table.getRowModel().rows; columns come from table.getVisibleLeafColumns(). Use computed options so counts and scroll targets update.

Implement the geometry

Give the scroll container a bounded height and positioning context, create a spacer using getTotalSize(), and translate/measure virtual items. Follow the grid/flex examples for dynamic row heights and sticky headers.

Coordinate infinite fetching

Fetch near the last virtual item only while totalFetched < serverRowCount and no request is active. Manual sorting means the server must return the sorted order and a sort change normally resets pages.

Common Mistakes

HIGH Passing a plain options snapshot

Wrong:

useVirtualizer({ count: rows.value.length, getScrollElement })

Correct:

useVirtualizer(computed(() => ({ count: rows.value.length, getScrollElement })))

Computed options keep the virtual range synchronized with Vue’s current model.

Source: examples/vue/virtualized-rows/src/App.vue

HIGH Virtualizing source arrays

Wrong:

const rows = computed(() => data.value)

Correct:

const rows = computed(() => table.getRowModel().rows)

Source arrays do not represent Table’s current filtering, sorting, expansion, or pagination.

Source: docs/framework/vue/guide/virtualization.md

HIGH Assuming Virtual provides CSS

Wrong:

<div v-for="item in virtualRows" :key="item.key">{{ rows[item.index].id }}</div>

Correct:

<div :style="{ height: `${totalSize}px`, position: 'relative' }"><div style="position:absolute"></div></div>

Virtual provides measurements, not spacer layout, transforms, sticky positioning, or Table column widths.

Source: examples/vue/virtualized-columns/src/App.vue

API Discovery

Inspect installed @tanstack/vue-table/dist/ and @tanstack/vue-virtual/dist/; use the maintained Vue examples for exact row, column, and infinite layout combinations.

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.