虚拟滚动器是一种高效渲染大量数据的高性能方法。
import VirtualScroller from 'primevue/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 模板自定义项目,例如使用 骨架屏。
<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>
虚拟滚动器没有强制执行特定的角色,但您仍然可以使用任何 aria 角色和属性,因为任何有效的属性都会传递到容器元素。
组件不包含任何内置的交互元素。