vue虚拟滚动实现
vue虚拟滚动实现
虚拟滚动是一种优化长列表渲染性能的技术,通过仅渲染可视区域内的元素来减少DOM节点数量。以下是Vue中实现虚拟滚动的几种方法:
使用第三方库
推荐使用成熟的虚拟滚动库,如vue-virtual-scroller或vue-virtual-scroll-list。
安装vue-virtual-scroller:
npm install vue-virtual-scroller
基本使用示例:
<template>
<RecycleScroller
class="scroller"
:items="items"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div class="item">{{ item.name }}</div>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
export default {
components: { RecycleScroller },
data() {
return {
items: Array(10000).fill().map((_, i) => ({ id: i, name: `Item ${i}` }))
}
}
}
</script>
<style>
.scroller {
height: 500px;
}
.item {
height: 50px;
display: flex;
align-items: center;
}
</style>
自定义实现
如果需要手动实现虚拟滚动,可以结合计算属性和滚动事件:

<template>
<div class="viewport" @scroll="handleScroll" ref="viewport">
<div class="scroll-container" :style="{ height: totalHeight + 'px' }">
<div
class="visible-items"
:style="{ transform: `translateY(${offset}px)` }"
>
<div
v-for="item in visibleItems"
:key="item.id"
class="item"
:style="{ height: itemHeight + 'px' }"
>
{{ item.content }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: Array(10000).fill().map((_, i) => ({
id: i,
content: `Item ${i}`
})),
itemHeight: 50,
viewportHeight: 500,
offset: 0
}
},
computed: {
totalHeight() {
return this.items.length * this.itemHeight
},
visibleCount() {
return Math.ceil(this.viewportHeight / this.itemHeight) + 2
},
startIndex() {
return Math.floor(this.offset / this.itemHeight)
},
visibleItems() {
return this.items.slice(
this.startIndex,
this.startIndex + this.visibleCount
)
}
},
methods: {
handleScroll() {
this.offset = this.$refs.viewport.scrollTop
}
}
}
</script>
<style>
.viewport {
height: 500px;
overflow-y: auto;
}
.scroll-container {
position: relative;
}
.visible-items {
position: absolute;
width: 100%;
}
.item {
display: flex;
align-items: center;
border-bottom: 1px solid #eee;
}
</style>
性能优化技巧
- 使用
requestAnimationFrame节流滚动事件 - 避免在渲染函数中进行复杂计算
- 对静态内容使用
Object.freeze冻结数据 - 合理设置缓冲区大小(多渲染一些不可见项目)
注意事项
- 需要确保所有项目具有固定高度(或能计算高度)
- 动态高度项目需要更复杂的实现
- 服务器端渲染(SSR)需要特殊处理
- 移动端可能需要考虑滚动惯性
虚拟滚动能显著提升包含大量数据列表的性能,但实现时需要考虑滚动体验、动态内容加载等细节问题。






