# VirtualList 虚拟列表 3.1.80

虚拟列表是一种高性能的列表渲染技术,适用于需要渲染大量数据的场景。它通过只渲染可视区域内的元素,大大减少了DOM节点数量,提升了页面性能。

# 平台差异说明

App(vue) App(nvue) H5 小程序

# 基本使用

通过[listData]传入需要渲染的数据列表,通过插槽自定义列表项内容。

<template>
  <view>
    <up-virtual-list
      :list-data="list"
      :item-height="60"
    >
      <template #item="{ item, index }">
        <view class="list-item">
          <text>Item {{ item.id }}: {{ item.name }}</text>
        </view>
      </template>
    </up-virtual-list>
  </view>
</template>
<style scoped>
.list-item {
  height: 60px;
  display: flex;
  align-items: center;
  padding: 0 15px;
  border-bottom: 1px solid #f0f0f0;
}
</style>
<script setup>
import { ref, onMounted } from 'vue';

const list = ref([]);

onMounted(() => {
  // 模拟大量数据
  list.value = Array.from({ length: 10000 }, (_, index) => ({
    id: index + 1,
    name: `Item ${index + 1}`
  }));
});
</script>
<script>
export default {
  data() {
    return {
      list: []
    }
  },
  mounted() {
    // 模拟大量数据
    this.list = Array.from({ length: 10000 }, (_, index) => ({
      id: index + 1,
      name: `Item ${index + 1}`
    }))
  }
}
</script>

# 设置列表高度

通过[height]设置虚拟列表容器的高度。

<template>
  <view>
    <up-virtual-list
      :list-data="list"
      :height="400"
      :item-height="50"
    >
      <template #item="{ item }">
        <view class="list-item">
          <text>{{ item.name }}</text>
        </view>
      </template>
    </up-virtual-list>
  </view>
</template>
<script setup>
import { ref } from 'vue';

const list = ref(Array.from({ length: 1000 }, (_, index) => ({
  id: index,
  name: `Item ${index}`
})));
</script>
<script>
export default {
  data() {
    return {
      list: Array.from({ length: 1000 }, (_, index) => ({
        id: index,
        name: `Item ${index}`
      }))
    }
  }
}
</script>

# 自定义缓冲区

通过[buffer]设置可视区域外的缓冲区大小,提升滚动体验。

<template>
  <view>
    <up-virtual-list
      :list-data="list"
      :item-height="60"
      :buffer="10"
    >
      <template #item="{ item }">
        <view class="list-item">
          <text>{{ item.name }}</text>
        </view>
      </template>
    </up-virtual-list>
  </view>
</template>
<script setup>
import { ref } from 'vue';

const list = ref(Array.from({ length: 5000 }, (_, index) => ({
  id: index,
  name: `Item ${index}`
})));
</script>
<script>
export default {
  data() {
    return {
      list: Array.from({ length: 5000 }, (_, index) => ({
        id: index,
        name: `Item ${index}`
      }))
    }
  }
}
</script>

# Props

参数 说明 类型 默认值 可选值
listData 列表数据 Array [] -
itemHeight 列表项高度 Number 50 -
height 列表容器高度 String | Number 100% -
buffer 缓冲区大小(可视区域外的渲染数量) Number 4 -
keyField 唯一标识字段名 String id -
scrollTop 当前滚动位置 Number 0 -

# Events

事件名 说明 回调参数
update:scrollTop 滚动时更新scrollTop值 scrollTop
scroll 滚动时触发 scrollTop

# Slots

名称 说明 SlotProps
default 列表项内容 { item, index }

# 方法

通过 ref 可以获取到虚拟列表实例并调用方法:

方法名 说明 参数
getVisibleRange() 获取可见项范围 -

# 监听滚动事件

<template>
  <view>
    <up-virtual-list
      :list-data="list"
      :item-height="60"
      :height="400"
      :scroll-top.sync="currentScrollTop"
      @scroll="handleScroll"
    >
      <template #default="{ item, index }">
        <view class="list-item">
          <text>{{ item.name }}</text>
        </view>
      </template>
    </up-virtual-list>
    
    <view class="scroll-info">
      <text>当前滚动位置: {{ currentScrollTop }}</text>
    </view>
  </view>
</template>
```js

</div>

<div class="options-api">
```js
<script>
export default {
  data() {
    return {
      list: Array.from({ length: 3000 }, (_, index) => ({
        id: index,
        name: `Item ${index}`
      })),
      currentScrollTop: 0
    }
  },
  methods: {
    handleScroll(scrollTop) {
      console.log('滚动位置:', scrollTop)
    }
  }
}
</script>
```

# 注意事项

  1. 每个列表项的高度必须固定且一致,通过itemHeight属性设置
  2. 数据量越大,虚拟列表的性能优势越明显
  3. 如果需要动态高度的列表项,请使用其他解决方案
  4. 使用keyField指定唯一标识字段,避免渲染异常
  5. 可通过[buffer]调整缓冲区大小以平衡性能和体验
  6. 组件会自动测量容器高度,也可以通过[height]属性手动指定