Skip to content

Virtual Window (useVirtualWindow)

useVirtualWindow is a Vue composable for virtual scroll window calculation, used for visible range computation in virtual lists and virtual tables.

It helps you easily handle: large data list rendering, table virtual scrolling, and solving lag issues caused by too many nodes.

Source code: GitHub

Usage

vue
<script setup>
import { ref, computed } from 'vue'
import { useVirtualWindow } from 'see-u-ui'

const list = ref(Array.from({ length: 10000 }, (_, i) => `Item ${i}`))
const scrollTop = ref(0)

const virtual = useVirtualWindow({
  total: computed(() => list.value.length),
  itemSize: 50,           // Item height 50px
  viewportSize: 400,      // Viewport height 400px
  buffer: 5               // Buffer 5 items above and below
})

// Render range
const startIndex = virtual.startIndex
const endIndex = virtual.endIndex
const translateOffset = virtual.translateOffset
</script>
vue
<script setup>
import { ref, computed } from 'vue'
import { useVirtualWindow } from 'see-u-ui'

const list = ref([...])

const virtual = useVirtualWindow({
  total: computed(() => list.value.length),
  itemSize: 50,
  viewportSize: 400,
  dynamic: true,                    // Enable dynamic height
  estimatedItemHeight: 80,          // Estimated height
  scrollOffset: currentScrollTop
})
</script>

Calculation Rules

Fixed Height Mode

visibleStart = Math.floor(scrollOffset / itemSize)
visibleEnd = visibleStart + visibleCount + buffer * 2
translateOffset = visibleStart * itemSize
totalSize = total * itemSize

Dynamic Height Mode

Uses estimatedItemSize instead of itemSize for calculation, totalSize = total * estimatedItemSize

API

useVirtualWindow(options)

Virtual window calculation Hook

ParameterTypeDefaultDescription
options.totalRef<number> | numberTotal list length
options.itemSizeRef<number> | numberItem size (px), primary path for fixed height
options.viewportSizeRef<number> | numberViewport size (px)
options.buffernumber5Buffer item count
options.estimatedItemSizeRef<number> | numberundefinedEstimated item size (px) for dynamic mode
options.dynamicRef<boolean> | booleanfalseEnable dynamic height
options.scrollOffsetRef<number> | numberundefinedScroll offset (px)

Returns:

Property/MethodTypeDescription
visibleStartComputedRef<number>Visible range start index (excl. buffer)
visibleEndComputedRef<number>Visible range end index (excl. buffer)
visibleCountComputedRef<number>Visible item count in viewport
translateOffsetComputedRef<number>Placeholder offset (px)
totalSizeComputedRef<number>Total content size (px)
startIndexComputedRef<number>Actual render start index (incl. buffer)
endIndexComputedRef<number>Actual render end index (incl. buffer)
rangeComputedRef<VirtualWindowRange>Visible range object
scrollOffsetComputedRef<number>Current scroll offset
setScrollOffset(offset: number) => voidUpdate scroll offset
visibleIndicesComputedRef<number[]>Index array within visible range

VirtualWindowRange

typescript
interface VirtualWindowRange {
  visibleStart: number    // Visible range start index
  visibleEnd: number      // Visible range end index
  translateOffset: number // Placeholder offset (px)
  totalSize: number       // Total content size (px)
}

Liao ICP No. 2025070134