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 角色和屬性,因為任何有效的屬性都會傳遞到容器元素。
元件不包含任何內建的互動式元素。