WindowScroller
WindowScroller is the window-based version of RecycleScroller.
Use it when the browser window is the scroll container and the list should stay in normal page flow with content above or below it.
When to use it
- The page itself scrolls, not an inner fixed-height container.
- You want a documented public API for window scrolling instead of relying on
pageMode. - You still want the same pooled rendering,
shift, cache restore, and imperative scrolling helpers asRecycleScroller.
Basic usage
<script setup lang="ts">
import { ref } from 'vue'
import { WindowScroller } from 'vue-virtual-scroller'
const rows = ref(
Array.from({ length: 1000 }, (_, index) => ({
id: index + 1,
label: `Row ${index + 1}`,
})),
)
</script>
<template>
<section class="page-content-before">
Content before the list
</section>
<WindowScroller
v-slot="{ item }"
:items="rows"
:item-size="40"
key-field="id"
>
<div class="row">
{{ item.label }}
</div>
</WindowScroller>
</template>TypeScript generics
WindowScroller uses the same generic component typing as RecycleScroller. With Vue 3.3+, the item slot prop is inferred from items automatically:
<script setup lang="ts">
import { ref } from 'vue'
interface Row {
id: number
label: string
}
const rows = ref<Row[]>([])
</script>
<template>
<WindowScroller :items="rows" :item-size="40">
<template #default="{ item }">
{{ item.label }}
</template>
</WindowScroller>
</template>If you want the same item type to flow through the headless window-scrolling helpers, use useWindowScroller with an explicit generic.
keyField follows the same contract as RecycleScroller: pass a string field name or a resolver function with the signature (item, index) => string | number.
How it behaves
- The list stays in normal page flow instead of owning its own fixed-height scrollbox.
- Visibility is computed from the browser viewport, so surrounding page content can sit before or after the list naturally.
- The component still uses pooled rendering, recycled views,
shift, and cache restore exactly likeRecycleScroller.
Props
WindowScroller accepts the same core props as RecycleScroller, except it always uses window-based scrolling.
The most commonly used props are:
itemskeyFielddirectionitemSizegridItemsitemSecondarySizeminItemSizesizeFieldtypeFieldbuffershiftcachedisableTransformprerenderemitUpdateupdateIntervallistTagitemTaglistClassitemClass
Use itemSize: null when each item already knows its size through sizeField. You can also pass itemSize as a resolver function (item, index) => number when sizes are already known in memory. If the DOM needs to measure unknown item sizes after render, switch to DynamicScroller.
gridItems still requires a fixed numeric itemSize. Function-based item sizes are not supported in grid mode.
Slots
WindowScroller keeps the same slot structure as RecycleScroller:
- Default slot props:
item,index,active before: content rendered before the pooled listafter: content rendered after the pooled listempty: shown whenitemsis empty
The default slot is still the simplest choice when the bundled wrapper markup already fits your UI.
Events
WindowScroller emits the same events as RecycleScroller:
resizevisiblehiddenupdate(startIndex, endIndex, visibleStartIndex, visibleEndIndex)whenemitUpdateis enabled
Exposed methods
With a template ref created via useTemplateRef, WindowScroller exposes the same navigation helpers as the core scroller:
scrollToItem(index, options?)scrollToPosition(position, options?)getScroll()findItemIndex(offset)getItemOffset(index)getItemSize(index)cacheSnapshotrestoreCache(snapshot)updateVisibleItems(itemsChanged, checkPositionDiff?)
WindowScroller vs pageMode
- Prefer
WindowScrollerfor new code when window scrolling is intentional. - Keep using
pageModeonRecycleScrollerwhen you only need the older compatibility behavior and do not want to switch components yet.