虚拟滚动通过只渲染可视区域及缓冲区元素来优化长列表性能,采用固定高度容器、占位层撑高、绝对定位渲染层三层结构实现;Vue 3 推荐使用 vue-virtual-scroller@next,配合 RecycleScroller 组件快速接入,拖拽时需将 draggable 作用于单项并确保数据源绑定与缓冲区设置。

直接用虚拟滚动,核心是只渲染当前能看到的那几项,而不是把几千条数据全塞进 DOM。它不改变数据逻辑,只改变渲染方式,对现有业务侵入小、见效快。
为什么传统长列表会卡
列表一过千条,浏览器就得创建同等数量的 DOM 节点。内存飙升、重排重绘频繁、滚动掉帧——尤其在中低端手机上,滑动可能直接卡死或白屏。这不是 Vue 本身的问题,而是原生 Web 渲染机制的瓶颈。
虚拟滚动怎么起作用
它靠三层结构配合实现“视觉欺骗”:
-
外层容器:固定高度 +
overflow: auto,用户实际滚动的地方 -
占位层:一个空 div,高度设为
总条数 × 单项高度,撑出真实滚动条比例 -
渲染层:绝对定位,用
transform: translateY()动态挪到可视位置,只挂载当前窗口内及上下缓冲区的节点
Vue 里怎么快速落地
推荐用 vue-virtual-scroller@next(Vue 3 专用),不用从零造轮子:
立即学习“前端免费学习笔记(深入)”;
- 安装:
npm install vue-virtual-scroller@next - 全局注册(
main.js)并引入配套 CSS - 模板中用
<RecycleScroller>替换原v-for,传入:items和:item-size - 每项必须有唯一
key-field,高度要固定或通过函数动态计算
拖拽场景特别注意
如果列表还带拖拽排序(比如用 Vue.Draggable),不能把 draggable 直接套在 RecycleScroller 外层——会破坏滚动计算。正确做法是:
- 让
draggable包裹每一项内容,而非整个列表 - 确保
v-model绑定的是原始数据源(不是visibleItems) - 设置足够缓冲区(如
buffer-size="5"),避免拖拽时目标项突然消失 - 拖拽过程中监听事件,手动校准被拖元素的视觉位置



















