vue实现触底加载
触底加载的实现原理
触底加载的核心是监听滚动事件,判断页面是否滚动到底部。当滚动条接近底部时触发数据加载。Vue中可以通过结合v-infinite-scroll指令或手动监听滚动事件实现。

使用v-infinite-scroll指令(Element UI)
安装Element UI后,可直接使用其内置的无限滚动指令:

<template>
<div
v-infinite-scroll="loadMore"
infinite-scroll-disabled="busy"
infinite-scroll-distance="100"
>
<div v-for="item in list" :key="item.id">{{ item.content }}</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
busy: false,
page: 1
}
},
methods: {
loadMore() {
this.busy = true;
fetch(`/api/data?page=${this.page}`)
.then(res => res.json())
.then(data => {
this.list.push(...data);
this.page++;
this.busy = false;
});
}
}
}
</script>
手动实现滚动监听
如果没有使用UI库,可通过原生滚动监听实现:
<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>
<script>
export default {
data() {
return {
list: [],
loading: false,
page: 1
}
},
methods: {
handleScroll(e) {
const { scrollTop, clientHeight, scrollHeight } = e.target;
const threshold = 100;
if (scrollHeight - (scrollTop + clientHeight) < threshold && !this.loading) {
this.loadMore();
}
},
loadMore() {
this.loading = true;
fetch(`/api/data?page=${this.page}`)
.then(res => res.json())
.then(data => {
this.list.push(...data);
this.page++;
this.loading = false;
});
}
}
}
</script>
<style>
.scroll-container {
height: 500px;
overflow-y: auto;
}
</style>
使用Intersection Observer API
现代浏览器支持更高效的交叉观察器API:
<template>
<div class="container">
<div v-for="item in list" :key="item.id">{{ item.content }}</div>
<div ref="loader" v-if="hasMore">加载中...</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
hasMore: true,
page: 1,
observer: null
}
},
mounted() {
this.observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting && this.hasMore) {
this.loadMore();
}
});
this.observer.observe(this.$refs.loader);
},
beforeDestroy() {
this.observer.disconnect();
},
methods: {
loadMore() {
fetch(`/api/data?page=${this.page}`)
.then(res => res.json())
.then(data => {
if (data.length === 0) this.hasMore = false;
this.list.push(...data);
this.page++;
});
}
}
}
</script>
注意事项
- 节流处理:滚动事件可能频繁触发,需要添加防抖/节流
- 加载状态管理:避免重复请求
- 数据为空判断:当没有更多数据时应停止加载
- 错误处理:添加请求失败的处理逻辑
- 移动端适配:考虑移动端的滚动容器差异






