Skip to content

useVirtualList

Category
Export Size
1.74 kB
Last Changed
2 months ago

WARNING

Consider using vue-virtual-scroller instead, if you are looking for more features.

Create virtual lists with ease. Virtual lists (sometimes called virtual scrollers) allow you to render a large number of items performantly. They only render the minimum number of DOM nodes necessary to show the items within the container element by using the wrapper element to emulate the container element's full height.

Demo

Jump to index
Filter list by size
Row 0 (small)
Row 1 (large)
Row 2 (small)
Row 3 (large)
Row 4 (small)
Row 5 (large)
Row 6 (small)
Row 7 (large)
Row 8 (small)
Row 9 (large)
Row 10 (small)
Row 11 (large)
Row 12 (small)
Row 13 (large)
Row 14 (small)

Usage

Simple list

ts
import { 
useVirtualList
} from '@vueuse/core'
const {
list
,
containerProps
,
wrapperProps
} =
useVirtualList
(
Array
.
from
(
Array
.
from
({
length
: 99999 }).
keys
()),
{ // Keep `itemHeight` in sync with the item's row.
itemHeight
: 22,
}, )

Config

StateTypeDescription
itemHeightnumberensure that the total height of the wrapper element is calculated correctly.*
itemWidthnumberensure that the total width of the wrapper element is calculated correctly.*
overscannumbernumber of pre-rendered DOM nodes. Prevents whitespace between items if you scroll very quickly.

* The itemHeight or itemWidth must be kept in sync with the height of each row rendered. If you are seeing extra whitespace or jitter when scrolling to the bottom of the list, ensure the itemHeight or itemWidth is the same height as the row.

Reactive list

ts
import { 
useToggle
,
useVirtualList
} from '@vueuse/core'
import {
computed
} from 'vue'
const [
isEven
,
toggle
] =
useToggle
()
const
allItems
=
Array
.
from
(
Array
.
from
({
length
: 99999 }).
keys
())
const
filteredList
=
computed
(() =>
allItems
.
filter
(
i
=>
isEven
.
value
?
i
% 2 === 0 :
i
% 2 === 1))
const {
list
,
containerProps
,
wrapperProps
} =
useVirtualList
(
filteredList
,
{
itemHeight
: 22,
}, )
vue
<template>
  <
p
>Showing {{ isEven ? 'even' : 'odd' }} items</
p
>
<
button
@
click
="toggle">
Toggle Even/Odd </
button
>
<
div
v-bind="containerProps"
style
="height: 300px">
<
div
v-bind="wrapperProps">
<
div
v-for="
item
in list"
:key
="
item
.index"
style
="height: 22px">
Row: {{
item
.data }}
</
div
>
</
div
>
</
div
>
</template>

Horizontal list

ts
import { 
useVirtualList
} from '@vueuse/core'
const
allItems
=
Array
.
from
(
Array
.
from
({
length
: 99999 }).
keys
())
const {
list
,
containerProps
,
wrapperProps
} =
useVirtualList
(
allItems
,
{
itemWidth
: 200,
}, )
vue
<template>
  <
div
v-bind="containerProps"
style
="height: 300px">
<
div
v-bind="wrapperProps">
<
div
v-for="
item
in list"
:key
="
item
.index"
style
="width: 200px">
Row: {{
item
.data }}
</
div
>
</
div
>
</
div
>
</template>

Component Usage

This function also provides a renderless component version via the @vueuse/components package. Learn more about the usage.

vue
<template>
  <UseVirtualList 
:list
="list"
:options
="options"
height
="300px">
<template #default="
props
">
<!-- you can get current item of list here --> <
div
style
="height: 22px">
Row {{
props
.index }} {{
props
.data }}
</
div
>
</template> </UseVirtualList> </template>

To scroll to a specific element, the component exposes scrollTo(index: number) => void.

Type Declarations

Show Type Declarations
ts
type 
UseVirtualListItemSize
= number | ((
index
: number) => number)
export interface UseHorizontalVirtualListOptions extends UseVirtualListOptionsBase { /** * item width, accept a pixel value or a function that returns the width * * @default 0 */
itemWidth
:
UseVirtualListItemSize
} export interface UseVerticalVirtualListOptions extends UseVirtualListOptionsBase { /** * item height, accept a pixel value or a function that returns the height * * @default 0 */
itemHeight
:
UseVirtualListItemSize
} export interface UseVirtualListOptionsBase { /** * the extra buffer items outside of the view area * * @default 5 */
overscan
?: number
} export type
UseVirtualListOptions
=
| UseHorizontalVirtualListOptions | UseVerticalVirtualListOptions export interface
UseVirtualListItem
<
T
> {
data
:
T
index
: number
} export interface
UseVirtualListReturn
<
T
> {
list
:
Ref
<
UseVirtualListItem
<
T
>[]>
scrollTo
: (
index
: number) => void
containerProps
: {
ref
:
Ref
<HTMLElement | null>
onScroll
: () => void
style
:
StyleValue
}
wrapperProps
:
ComputedRef
<{
style
:
| {
width
: string
height
: string
marginTop
: string
} | {
width
: string
height
: string
marginLeft
: string
display
: string
} }> } /** * Please consider using [`vue-virtual-scroller`](https://github.com/Akryum/vue-virtual-scroller) if you are looking for more features. */ export declare function
useVirtualList
<
T
= any>(
list
:
MaybeRef
<readonly
T
[]>,
options
:
UseVirtualListOptions
,
):
UseVirtualListReturn
<
T
>

Source

SourceDemoDocs

Contributors

Anthony Fu
Anthony Fu
IlyaL
wheat
IlyaL
SerKo
Zhong
Rebecca Stevens
reslear
Eliamar Tani
Reuben
karukenert
Ruben Laguna
Minh Anh Nguyen
vaakian X
Nikola Begedin
Eric Skaliks
vaakian X
Maxim Brynze
Jelf
Jessica Sachs
Che Guevara

Changelog

v14.0.0-alpha.0 on
8c521 - feat(components)!: refactor components and make them consistent (#4912)
v13.6.0 on
d2381 - fix: resolve invalid watch source (#4857)
v12.8.0 on
7432f - feat(types): deprecate MaybeRef and MaybeRefOrGetter in favor of Vue's native (#4636)
v12.5.0 on
f3cc7 - fix: allow readonly arrays as input (#4504)
v12.0.0-beta.1 on
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
v10.10.0 on
4636f - fix: add containerRef to watch list (#3855)
v10.7.1 on
286c3 - fix: ensure component applies overflow style (#3626)
v10.7.0 on
fccf2 - feat: upgrade deps (#3614)
v10.6.1 on
3d6b9 - fix: .style can be undefined

Released under the MIT License.

Join the Biggest FREE AI-Driven Development Event for Vue Developers
Save My Seat