Skip to content

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(99999).keys()),
  {
    // Keep `itemHeight` in sync with the item's row.
    itemHeight: 22,
  },
)

配置

¥Config

状态类型描述
itemHeightnumber确保正确计算 wrapper 元素的总高度。*
itemWidthnumber确保正确计算 wrapper 元素的总宽度。*
overscannumber预渲染 DOM 节点的数量。如果滚动速度非常快,可以防止项目之间出现空白。
  • itemHeightitemWidth 必须与渲染的每行的高度保持同步。如果你在滚动到列表底部时看到额外的空白或抖动,请确保 itemHeightitemWidth 与行的高度相同。

¥* 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(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(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.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>

源代码

源代码示例文档

变更日志

No recent changes

VueUse 中文网 - 粤ICP备13048890号