vue实现伪加载列表
Vue 实现伪加载列表
伪加载列表(也称为虚拟滚动或无限滚动)是一种优化长列表渲染性能的技术,通过仅渲染可视区域内的元素来减少 DOM 节点数量。以下是实现方法:
使用 vue-virtual-scroller 库
安装 vue-virtual-scroller 库:
npm install vue-virtual-scroller
在 Vue 项目中引入并使用:
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
export default {
components: { RecycleScroller },
data() {
return {
items: [], // 你的数据列表
itemSize: 50 // 每个项目的高度
}
}
}
模板中使用:

<RecycleScroller
class="scroller"
:items="items"
:item-size="itemSize"
key-field="id"
>
<template v-slot="{ item }">
<!-- 渲染单个列表项 -->
<div>{{ item.name }}</div>
</template>
</RecycleScroller>
自定义实现虚拟滚动
监听滚动事件并计算可视区域:
data() {
return {
visibleItems: [],
startIndex: 0,
endIndex: 20,
itemHeight: 50,
containerHeight: 500
}
},
mounted() {
this.updateVisibleItems()
window.addEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
this.updateVisibleItems()
},
updateVisibleItems() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
this.startIndex = Math.floor(scrollTop / this.itemHeight)
this.endIndex = Math.min(
this.startIndex + Math.ceil(this.containerHeight / this.itemHeight),
this.items.length
)
this.visibleItems = this.items.slice(this.startIndex, this.endIndex)
}
}
模板结构:

<div class="scroll-container" :style="{ height: `${items.length * itemHeight}px` }">
<div
class="item"
v-for="item in visibleItems"
:key="item.id"
:style="{ transform: `translateY(${item.index * itemHeight}px)` }"
>
{{ item.content }}
</div>
</div>
使用 CSS 优化
为滚动容器和列表项添加样式:
.scroll-container {
position: relative;
overflow-y: auto;
}
.item {
position: absolute;
width: 100%;
box-sizing: border-box;
}
性能考虑
- 使用
key属性确保高效的 DOM 复用 - 避免在列表项中使用复杂的计算属性
- 考虑使用
Object.freeze()冻结静态数据 - 对于超长列表,可以结合分页加载机制
动态加载数据
结合 API 实现无限滚动:
async loadMore() {
if (this.isLoading) return
this.isLoading = true
const newItems = await fetchMoreData()
this.items = [...this.items, ...newItems]
this.isLoading = false
}
监听滚动到底部事件:
handleScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement
if (scrollTop + clientHeight >= scrollHeight - 100) {
this.loadMore()
}
}






