Skip to content

useVirtualList

类别
导出体积
1.8 kB
上次更改
4 months ago

WARNING

如果你正在寻找更多功能,请考虑使用 vue-virtual-scroller

轻松创建虚拟列表。虚拟列表 (有时称为 virtual scrollers) 允许你高效地渲染大量项目。它们只渲染必要的最小数量的 DOM 节点,以通过使用 wrapper 元素模拟容器元素的完整高度来显示 container 元素中的项目。

示例

跳转到索引
按尺寸筛选列表

用法

简单列表

typescript
import { useVirtualList } from '@vueuse/core'

const { list, containerProps, wrapperProps } = useVirtualList(
  Array.from(Array.from({ length: 99999 }).keys()),
  {
    // 确保 `itemHeight` 与每行的高度保持同步。
    itemHeight: 22,
  },
)

配置

状态类型描述
itemHeightnumber确保正确计算 wrapper 元素的总高度。*
itemWidthnumber确保正确计算 wrapper 元素的总宽度。*
overscannumber预渲染的 DOM 节点数量。如果你快速滚动,可防止项目之间出现空白。

* 必须将 itemHeightitemWidth 与呈现的每行的高度保持同步。如果在滚动到列表底部时看到额外的空白或抖动,请确保 itemHeightitemWidth 与行的高度相同。

响应式列表

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.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>

源码

源码演示文档

贡献者

Anthony Fu
一纸忘忧
Anthony Fu
wheat
Eliamar Tani
Reuben
karukenert
Ruben Laguna
Minh Anh Nguyen
vaakian X
Nikola Begedin
Eric Skaliks
vaakian X
Maxim Brynze
Jelf
Jessica Sachs
Che Guevara

更新日志

v10.10.0 on 5/27/2024
4636f - fix: add containerRef to watch list (#3855)
v10.7.1 on 12/27/2023
286c3 - fix: ensure component applies overflow style (#3626)
v10.7.0 on 12/5/2023
fccf2 - feat: upgrade deps (#3614)
v10.6.1 on 11/13/2023
3d6b9 - fix: .style can be undefined
v9.11.0 on 1/17/2023
d5321 - fix(components): mark defineComponent as pure (#2623)
25f6e - fix: List sometimes missing elements (#2477)
v9.10.0 on 1/3/2023
9f495 - feat(useVirutalList): expose scrollTo in component (#2397)
v9.4.0 on 10/25/2022
bceda - feat: horizontal list (#2310)