vue实现滚动列表插件
Vue 实现滚动列表插件的方法
使用第三方库(如 vue-virtual-scroller)
安装 vue-virtual-scroller 库,适用于大数据量的虚拟滚动场景。通过动态渲染可视区域内的元素减少 DOM 节点数量,提升性能。

npm install vue-virtual-scroller
在 Vue 组件中引入并配置:

<template>
<RecycleScroller
class="scroller"
:items="list"
:item-size="50"
key-field="id"
>
<template v-slot="{ item }">
<div class="item">{{ item.name }}</div>
</template>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller';
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
export default {
components: { RecycleScroller },
data() {
return {
list: Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` })),
};
},
};
</script>
<style>
.scroller {
height: 300px;
}
.item {
height: 50px;
line-height: 50px;
}
</style>
原生实现滚动列表
通过监听滚动事件动态计算显示范围,结合 CSS 实现平滑滚动效果。
<template>
<div class="scroll-container" @scroll="handleScroll">
<div class="scroll-content" :style="{ height: totalHeight + 'px' }">
<div
v-for="item in visibleItems"
:key="item.id"
class="item"
:style="{ transform: `translateY(${item.offset}px)` }"
>
{{ item.name }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` })),
itemHeight: 50,
startIndex: 0,
visibleCount: 0,
};
},
computed: {
totalHeight() {
return this.list.length * this.itemHeight;
},
visibleItems() {
return this.list.slice(
this.startIndex,
this.startIndex + this.visibleCount
).map(item => ({
...item,
offset: this.startIndex * this.itemHeight,
}));
},
},
mounted() {
this.visibleCount = Math.ceil(this.$el.clientHeight / this.itemHeight);
},
methods: {
handleScroll(e) {
this.startIndex = Math.floor(e.target.scrollTop / this.itemHeight);
},
},
};
</script>
<style>
.scroll-container {
height: 300px;
overflow-y: auto;
}
.scroll-content {
position: relative;
}
.item {
position: absolute;
height: 50px;
line-height: 50px;
width: 100%;
}
</style>
结合 CSS Scroll Snap
利用 CSS 的 scroll-snap-type 实现精准滚动定位,适合分页或卡片式列表。
<template>
<div class="snap-container">
<div v-for="item in list" :key="item.id" class="snap-item">
{{ item.name }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: Array.from({ length: 10 }, (_, i) => ({ id: i, name: `Item ${i}` })),
};
},
};
</script>
<style>
.snap-container {
height: 300px;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
.snap-item {
height: 100%;
scroll-snap-align: start;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #eee;
}
</style>
性能优化建议
- 大数据量优先使用虚拟滚动(如
vue-virtual-scroller)。 - 避免在滚动事件中执行复杂逻辑,使用防抖或节流控制频率。
- 固定列表项高度可提升计算效率,动态高度需额外处理。
- 使用 CSS
will-change属性优化渲染性能:.scroll-content { will-change: transform; }






