Skip to content
🌏 Translated with the assistance of DeepSeek and ChatGPT

Virtual List

Used to display extremely long lists, where only the visible parts are actually rendered. The component can render smoothly with data on the order of 100,000 items (more data is also possible, but the content may be truncated by the maximum height limit of the browser's DOM).

The virtual list adopts a hierarchical block partitioning strategy to maintain prefix sums. This data structure can control the time complexity of height calculation to O(n)O(\sqrt{n}), ultimately achieving smooth scrolling in large data volume scenarios.

WARNING

Browsers impose implementation-specific limits on the maximum scrollable / renderable height of DOM, which may cause content truncation or inaccessible regions in extreme cases. For example, in Edge 141.0.3537.71 the maximum visible pixel height is around 27 million pixels; content beyond that may be clipped or unreachable.

When using millions (or more) of items, watch the total height (itemsCount×averageItemHeightitemsCount \times averageItemHeight).

Basic Usage

The virtual list has dynamic heights for child elements by default. estimatedHeight sets the estimated height of elements during initialization, and it should usually be smaller than the height of most child elements.

Item #0
<template>
	<px-virtual-list :list="list" style="height: 500px" :estimated-height="20"></px-virtual-list>
</template>
<script lang="ts" setup>
import { shallowRef, h } from 'vue'

const list = shallowRef(
	Array.from({ length: 10000 })
		.fill(0)
		.map((_, index) => ({
			render: () => h('div', { style: `height: ${20 + index / 100}px;` }, [`Item #${index}`])
		}))
)
</script>

Fixed Height

When the child elements of the virtual list have fixed heights, or the average height of child elements can be accurately obtained, you can set fixedHeight and estimatedHeight to save performance.

Item #0
<template>
	<px-virtual-list
		:list="list"
		style="height: 500px"
		fixed-height
		:estimated-height="20"
	></px-virtual-list>
</template>
<script lang="ts" setup>
import { shallowRef, h } from 'vue'

const list = shallowRef(
	Array.from({ length: 10000 })
		.fill(0)
		.map((_, index) => ({
			render: () => h('div', { style: `height: 20px;` }, [`Item #${index}`])
		}))
)
</script>

API

VirtualListProps

AttributeTypeOptionalDefaultDescriptionVersion
list{ render: ValidContent; key?: string | number | symbol }[]TrueThe data array to render.0.0.3
fixedHeightbooleanTruefalseWhether to use fixed-height mode.0.0.3
estimatedHeightnumberTrue28Estimated item height in px (used for initialization and before measurements complete).0.0.3
buffernumberTrue10Number of buffer items to render before/after the visible window to reduce flicker during fast scrolls.0.0.3