vue如何实现触底加载
Vue 实现触底加载的方法
触底加载是常见的分页加载技术,通过监听滚动事件判断是否到达页面底部,触发数据加载。以下是 Vue 中的实现方式:

监听滚动事件
在 Vue 组件中,通过 @scroll 监听滚动事件,计算滚动位置与容器高度的关系:

<template>
<div class="scroll-container" @scroll="handleScroll">
<!-- 内容列表 -->
<div v-for="item in list" :key="item.id">{{ item.content }}</div>
<!-- 加载状态提示 -->
<div v-if="loading">加载中...</div>
</div>
</template>
export default {
data() {
return {
list: [], // 数据列表
loading: false, // 加载状态
page: 1, // 当前页码
};
},
methods: {
handleScroll(e) {
const container = e.target;
const scrollBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
if (scrollBottom < 50 && !this.loading) {
this.loadMore();
}
},
async loadMore() {
this.loading = true;
const newData = await fetchData(this.page++); // 模拟数据请求
this.list = [...this.list, ...newData];
this.loading = false;
},
},
};
使用 IntersectionObserver API
现代浏览器支持 IntersectionObserver,性能优于滚动事件监听:
<template>
<div class="scroll-container">
<div v-for="item in list" :key="item.id">{{ item.content }}</div>
<div ref="loader" v-if="!finished">{{ loading ? '加载中...' : '' }}</div>
</div>
</template>
export default {
data() {
return {
list: [],
loading: false,
page: 1,
finished: false,
};
},
mounted() {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !this.loading && !this.finished) {
this.loadMore();
}
});
observer.observe(this.$refs.loader);
},
methods: {
async loadMore() {
this.loading = true;
const newData = await fetchData(this.page++);
if (newData.length === 0) this.finished = true;
this.list = [...this.list, ...newData];
this.loading = false;
},
},
};
使用第三方库
若项目已引入 lodash,可利用 _.throttle 优化滚动事件:
import { throttle } from 'lodash';
export default {
methods: {
handleScroll: throttle(function(e) {
// 触底逻辑
}, 300),
},
};
注意事项
- 避免重复触发加载,需通过
loading状态控制 - 数据全部加载完成后,隐藏加载提示或显示“无更多数据”
- 移动端需考虑
clientHeight与scrollHeight的兼容性 - 组件销毁时移除事件监听或断开
IntersectionObserver
以上方法可根据具体场景选择,IntersectionObserver 方案更推荐用于现代浏览器环境。





