主题
useVirtualList
警告
如果你正在寻找更多特性,请考虑使用 vue-virtual-scroller
。
¥Consider using vue-virtual-scroller
instead, if you are looking for more features.
轻松创建虚拟列表。虚拟列表(有时称为 虚拟滚动条)允许你高效地渲染大量项目。它们仅通过使用 wrapper
元素模拟容器元素的完整高度来渲染显示 container
元素内的项目所需的最小数量的 DOM 节点。
¥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.
示例
Jump to index
Filter list by size
用法
¥Usage
简单清单
¥Simple list
typescript
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
状态 | 类型 | 描述 |
---|---|---|
itemHeight | number | 确保正确计算 wrapper 元素的总高度。* |
itemWidth | number | 确保正确计算 wrapper 元素的总宽度。* |
overscan | number | 预渲染 DOM 节点的数量。如果滚动速度非常快,可以防止项目之间出现空白。 |
itemHeight
或itemWidth
必须与渲染的每行的高度保持同步。如果你在滚动到列表底部时看到额外的空白或抖动,请确保itemHeight
或itemWidth
与行的高度相同。
¥* 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
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>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
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>
组件用法
¥Component 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>
要滚动到特定元素,该组件公开 scrollTo(index: number) => void
。
¥To scroll to a specific element, the component exposes scrollTo(index: number) => void
.
类型声明
显示类型声明
typescript
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<T[]>,
options: UseVirtualListOptions,
): UseVirtualListReturn<T>