Yt-UI
首页
快速开始
组件文档
首页
快速开始
组件文档
  • 表单组件

    • 输入框 Input
    • 多行输入框 Textarea
    • 开关 Switch
    • 多选框组 CheckboxGroup
    • 单选框组 RadioGroup
    • 滑块 Slider
    • 选择器 Picker
    • 日历 Calendar
    • 表单 Form
  • 展示组件

    • 头像 Avatar
    • 徽标 Badge
    • 卡片 Card
    • 标签 Tag
    • 步骤条 Steps
    • 结果页 Result
    • 空状态 Empty
    • 虚拟列表 VirtualList
  • 交互组件

    • 按钮 Button
    • 悬浮按钮 FAB
    • 图标 Icon
    • 搜索 Search
    • 分段器 Segment
    • 轮播 Swiper
    • 指示点 Dots
  • 反馈组件

    • 加载 Loading
    • 弹窗 Popup
    • 遮罩层 Overlay
    • 通告栏 NoticeBar
  • 导航组件

    • 标签栏 Tabbar
    • 顶部标签栏 TopTabbar
    • 折叠面板 Collapse
    • 课程表 Schedule
  • 布局组件

    • 分割线 Divider
    • 链接 Line
    • 可移动视图 MovableView

yt-virtual-list 虚拟列表组件

属性

属性名类型默认值说明
layout'single' | 'double' | 'waterfall''single'列表布局模式:单列、双列、瀑布流
rowGapnumber | string8行间距(px)
columnGapnumber | string8列间距(px)
bufferDistancenumber1200缓冲区距离(px),可见分块上下额外渲染的距离
listany[][]数据列表
itemKeystring''列表项唯一键,用于 Vue 的 key 标识
widthnumber | string'100%'列表宽度
heightnumber | string'100%'列表高度
chunkSizenumber20每个分块包含的列表项数量
estimatedSizenumber1000每个分块的预估高度(px),用于非可见分块的占位
showScrollbarbooleanfalse是否显示滚动条
refresherbooleanfalse是否开启下拉刷新
thresholdnumber50下拉刷新阈值(px)
triggeredbooleanfalse是否触发刷新状态
refresherBgColorstring'#fff'下拉刷新背景色
refresherStyle'black' | 'white' | 'none''black'下拉刷新样式

插槽

插槽名作用域参数说明
prefix-列表顶部内容
list-item{ item: any, index: number }列表项内容
suffix-列表底部内容

事件

事件名参数说明
scrolle: any滚动时触发
scrollToUpper-滚动到顶部
scrollToLower-滚动到底部
pull-下拉刷新触发
refresh-刷新状态
restore-刷新结束
abort-刷新中断

工作原理

本组件采用分块虚拟化策略优化长列表性能:

  • 将列表按 chunkSize 切分为多个分块
  • 通过 Intersection Observer 监测分块可见性
  • 仅渲染视口内(及前后 bufferDistance 缓冲区)的分块
  • 非可见分块使用 estimatedSize 高度占位
  • 支持自定义 prefix 和 suffix 插槽
  • 支持单列、双列、瀑布流三种布局模式

示例

基本用法(单列布局)

<yt-virtual-list 
  :list="listData" 
  itemKey="id" 
  :height="500"
  layout="single"
>
  <template v-slot:list-item="{ item, index }">
    <view class="list-item">{{ item.name }}</view>
  </template>
</yt-virtual-list>

双列布局

<yt-virtual-list
  :list="listData"
  itemKey="id"
  :height="600"
  layout="double"
  :rowGap="12"
  :columnGap="16"
>
  <template v-slot:list-item="{ item }">
    <view class="card">{{ item.name }}</view>
  </template>
</yt-virtual-list>

瀑布流布局

<yt-virtual-list
  :list="imageList"
  itemKey="id"
  :height="800"
  layout="waterfall"
  :bufferDistance="800"
  :chunkSize="10"
>
  <template v-slot:list-item="{ item }">
    <image :src="item.url" mode="widthFix" />
    <text>{{ item.title }}</text>
  </template>
</yt-virtual-list>

使用前后缀插槽

<yt-virtual-list :list="listData" itemKey="id" :height="500">
  <template v-slot:prefix>
    <view class="list-header">列表头部</view>
  </template>

  <template v-slot:list-item="{ item, index }">
    <view class="list-item">第{{ index + 1 }}项: {{ item.name }}</view>
  </template>

  <template v-slot:suffix>
    <view class="list-footer">列表底部</view>
  </template>
</yt-virtual-list>

下拉刷新

<template>
  <yt-virtual-list
    :list="listData"
    itemKey="id"
    :refresher="true"
    :triggered="isRefreshing"
    @refresh="handleRefresh"
  >
    <template v-slot:list-item="{ item }">
      <view>{{ item.text }}</view>
    </template>
  </yt-virtual-list>
</template>

<script setup>
import { ref } from 'vue'
const isRefreshing = ref(false)
const listData = ref([])
const handleRefresh = () => {
  isRefreshing.value = true
  setTimeout(() => isRefreshing.value = false, 1000)
}
</script>
最近更新:: 2026/5/11 23:19
Contributors: CHEEMS
Prev
空状态 Empty