vue实现虚拟滚动
虚拟滚动的基本概念
虚拟滚动是一种优化长列表渲染性能的技术,通过仅渲染可视区域内的元素,减少DOM节点数量,从而提升页面性能。适用于数据量大的表格、列表等场景。
实现虚拟滚动的核心步骤
计算可视区域数据
监听滚动事件,根据滚动位置计算当前可视区域的起始索引和结束索引。通过动态截取数据源中对应范围的数据进行渲染。
公式示例:
- 起始索引:
startIndex = Math.floor(scrollTop / itemHeight) - 结束索引:
endIndex = startIndex + visibleCount
其中visibleCount为可视区域能容纳的条目数,通常为Math.ceil(containerHeight / itemHeight) + buffer(buffer为缓冲条目数)。
具体实现方案
方案1:使用第三方库(推荐)
推荐使用 vue-virtual-scroller 或 vxe-table 等成熟库快速实现。
安装 vue-virtual-scroller:
npm install vue-virtual-scroller
示例代码:
<template>
<RecycleScroller
class="scroller"
:items="list"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div>{{ item.text }}</div>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller';
export default {
components: { RecycleScroller },
data() {
return {
list: [...Array(10000).keys()].map(i => ({ id: i, text: `Item ${i}` }))
};
}
};
</script>
<style>
.scroller {
height: 400px;
}
</style>
方案2:手动实现虚拟滚动
通过动态计算可视区域数据并监听滚动事件实现。
关键代码
<template>
<div class="virtual-scroll" @scroll="handleScroll">
<div class="scroll-content" :style="{ height: totalHeight + 'px' }">
<div
v-for="item in visibleItems"
:key="item.id"
:style="{ height: itemHeight + 'px', transform: `translateY(${item.offset}px)` }"
>
{{ item.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [...Array(10000).keys()].map(i => ({ id: i, text: `Item ${i}` })),
itemHeight: 50,
startIndex: 0,
visibleCount: 10,
scrollTop: 0
};
},
computed: {
totalHeight() {
return this.list.length * this.itemHeight;
},
visibleItems() {
const endIndex = Math.min(
this.startIndex + this.visibleCount,
this.list.length
);
return this.list
.slice(this.startIndex, endIndex)
.map((item, index) => ({
...item,
offset: (this.startIndex + index) * this.itemHeight
}));
}
},
methods: {
handleScroll(e) {
this.scrollTop = e.target.scrollTop;
this.startIndex = Math.floor(this.scrollTop / this.itemHeight);
}
}
};
</script>
<style>
.virtual-scroll {
height: 500px;
overflow-y: auto;
}
.scroll-content {
position: relative;
}
</style>
性能优化建议
- 固定高度:确保每条目的高度固定,避免动态计算导致的性能损耗。
- 缓冲区域:适当增加渲染范围(如多渲染 5-10 条),避免快速滚动时白屏。
- 减少重排:使用
transform替代top定位,减少布局计算。 - 节流滚动事件:使用
requestAnimationFrame或 Lodash 的throttle优化滚动事件。
通过以上方法,可高效实现虚拟滚动,显著提升大数据量列表的渲染性能。







