Vue 3 用虚拟滚动渲染十万行长列表:只渲染视口内的行,滚动不卡
test12026-11-0210 次阅读
长列表为什么会卡
把十万条数据直接 v-for 进 DOM,浏览器要同时维护十万个节点,首屏渲染、滚动重排、内存占用都会失控。虚拟滚动(windowing)的核心思路是:DOM 里永远只保留可视区域附近几十个节点,滚动时动态替换内容、用上下两个撑高占位元素维持原生滚动条。Vue 生态里 vue-virtual-scroller 已经把这个活儿干得很干净。
用 RecycleScroller 渲染定高列表
定高场景最简单:组件只需知道每行高度,就能算出要渲染哪一段。
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
import VueVirtualScroller from 'vue-virtual-scroller';
createApp(App).use(VueVirtualScroller).mount('#app');
<template>
<RecycleScroller
class="scroller"
:items="rows"
:item-size="56"
key-field="id"
v-slot="{ item }"
>
<div class="row">
<span class="title">{{ item.title }}</span>
<span class="meta">{{ item.author }} · {{ item.date }}</span>
</div>
</RecycleScroller>
</template>
<script setup>
const rows = Array.from({ length: 100000 }, (_, i) => ({
id: i,
title: `第 ${i + 1} 条记录`,
author: '张三',
date: '2026-11-02',
}));
</script>
<style scoped>
.scroller { height: 600px; }
.row { height: 56px; display: flex; align-items: center; padding: 0 16px; }
</style>
动态高度怎么办
行高不一时用 DynamicScroller,它会测量真实高度并缓存。注意要给每项稳定的 key,并尽量让内容高度可预测,否则频繁测量会带来额外开销。
<DynamicScroller :items="rows" :min-item-size="56" key-field="id">
<template #default="{ item, index }">
<DynamicScrollerItem :item="item" :active="index < 20" :data-index="index">
<div class="row">{{ item.title }}</div>
</DynamicScrollerItem>
</template>
</DynamicScroller>
踩坑提醒
- 容器必须给定高度:虚拟滚动靠固定视口高度换算渲染区间,父元素没高度会渲染 0 行。
- item-size 要真实:定高模式下给错值会导致滚到底部内容错位,宁可略大于真实高度。
- 海量数据优先分页+虚拟滚动组合:十万条没问题,但如果是无限流,配合“滚动到底加载下一页”比一次塞百万条更稳。
T
test1
文章作者
长列表为什么会卡 把十万条数据直接 v-for 进 DOM,浏览器要同时维护十万个节点,首屏渲染、滚动重排、内存占用都...
- 分类
- 技术
- 发布时间
- 2026-11-02
- 字数
- 约 1758 字
- 阅读
- 10 次
