useVirtualList
WARNING
如果您正在寻找更多功能,请考虑使用 vue-virtual-scroller
。
轻松创建虚拟列表。虚拟列表(有时称为 virtual scrollers)允许您高效地渲染大量项目。它们只渲染必要的最小数量的 DOM 节点,以通过使用 wrapper
元素模拟容器元素的完整高度来显示 container
元素中的项目。
Demo
跳转到索引
按尺寸筛选列表
用法
简单列表
typescript
import { useVirtualList } from '@vueuse/core'
const { list, containerProps, wrapperProps } = useVirtualList(
Array.from(Array.from({ length: 99999 }).keys()),
{
// 确保 `itemHeight` 与每行的高度保持同步。
itemHeight: 22,
},
)
配置
状态 | 类型 | 描述 |
---|---|---|
itemHeight | number | 确保正确计算 wrapper 元素的总高度。* |
itemWidth | number | 确保正确计算 wrapper 元素的总宽度。* |
overscan | number | 预渲染的 DOM 节点数量。如果您快速滚动,可防止项目之间出现空白。 |
* 必须将 itemHeight
或 itemWidth
与呈现的每行的高度保持同步。如果在滚动到列表底部时看到额外的空白或抖动,请确保 itemHeight
或 itemWidth
与行的高度相同。
响应式列表
typescript
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>显示 {{ isEven ? '偶数' : '奇数' }} 项目</p>
<button @click="toggle">
切换 偶数/奇数
</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>
水平列表
typescript
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>
组件用法
vue
<template>
<UseVirtualList :list="list" :options="options" height="300px">
<template #default="props">
<!-- 在这里获取列表的当前项目 -->
<div style="height: 22px">
Row {{ props.index }} {{ props.data }}
</div>
</template>
</UseVirtualList>
</template>
要滚动到特定元素,组件提供了 scrollTo(index: number) => void
方法。
类型声明
显示类型声明
typescript
type UseVirtualListItemSize = number | ((index: number) => number)
export interface UseHorizontalVirtualListOptions
extends UseVirtualListOptionsBase {
/**
* 每个项目的宽度,可以是像素值,也可以是返回宽度的函数
*
* @default 0
*/
itemWidth: UseVirtualListItemSize
}
export interface UseVerticalVirtualListOptions
extends UseVirtualListOptionsBase {
/**
* 每个项目的高度,可以是像素值,也可以是返回高度的函数
*
* @default 0
*/
itemHeight: UseVirtualListItemSize
}
export interface UseVirtualListOptionsBase {
/**
* 视图区域外的额外缓冲项目数量
*
* @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
}
}>
}
/**
* 如果您需要更多功能,请考虑使用 [`vue-virtual-scroller`](https://github.com/Akryum/vue-virtual-scroller)。
*/
export declare function useVirtualList<T = any>(
list: MaybeRef<T[]>,
options: UseVirtualListOptions,
): UseVirtualListReturn<T>
Source
贡献者
Anthony Fu
丶远方
Anthony Fu
wheat
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