VirtualScroller 是一种高效渲染大量数据的性能方法。
import VirtualScroller from 'primevue/virtualscroller';
VirtualScroller 需要 items 作为要显示的数据,itemSize 作为项目尺寸,以及组件上需要的 item 模板。此外,还需要基于要显示的项目总数的初始数组。视口的大小可以使用 scrollWidth、scrollHeight 属性直接配置,也可以使用 CSS width 和 height 样式配置。
<VirtualScroller :items="items" :itemSize="50" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
将 orientation 设置为 horizontal 可启用水平滚动。在这种情况下,itemSize 应指项目的宽度。
<VirtualScroller :items="items" :itemSize="50" orientation="horizontal" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px" :pt="{ content: 'flex flex-row' }">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="width: 50px; writing-mode: vertical-lr;">{{ item }}</div>
</template>
</VirtualScroller>
当 orientation 设置为 both 时,可以启用垂直和水平滚动。在这种模式下,itemSize 应该是一个数组,其中第一个值是项目的高度,第二个值是宽度。
<VirtualScroller :items="items" :itemSize="[50, 100]" orientation="both" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">
<template v-for="(el, index) of item" :key="index">
<div style="width: 100px">{{ el }}</div>
</template>
</div>
</template>
</VirtualScroller>
delay 属性在滚动期间添加一个以毫秒为单位的等待阈值,用于渲染优化。
<VirtualScroller :items="items" :itemSize="50" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
<VirtualScroller :items="items" :itemSize="50" :delay="150" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
<VirtualScroller :items="items" :itemSize="50" :delay="500" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
通过添加 showLoader 属性启用繁忙状态,默认情况下会使用模态框阻止 UI。或者,可以使用 loader 模板自定义项目,例如使用 Skeleton。
<VirtualScroller :items="items" :itemSize="50" showLoader :delay="250" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
<VirtualScroller :items="items" :itemSize="50" showLoader :delay="250" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
<template v-slot:loader="{ options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">
<Skeleton :width="options.even ? '60%' : '50%'" height="1.3rem" />
</div>
</template>
</VirtualScroller>
懒加载模式对于处理大型数据集非常方便,它不是加载整个数据,而是按需加载小块数据。要实现懒加载,请启用 lazy 属性并实现 onLazyLoad 回调以返回数据。
<VirtualScroller :items="lazyItems" :itemSize="50" showLoader :delay="250" :loading="lazyLoading" lazy @lazy-load="onLazyLoad" class="border border-surface-200 dark:border-surface-700 rounded" style="width: 200px; height: 200px">
<template v-slot:item="{ item, options }">
<div :class="['flex items-center p-2', { 'bg-surface-100 dark:bg-surface-700': options.odd }]" style="height: 50px">{{ item }}</div>
</template>
</VirtualScroller>
VirtualScroller 没有强制执行特定的角色,但您仍然可以使用任何 aria 角色和属性,因为任何有效的属性都会传递到容器元素。
组件不包含任何内置的交互式元素。