vue实现上拉翻页
vue实现上拉翻页的方法
监听滚动事件
在Vue组件中,通过@scroll或window.addEventListener监听滚动事件。判断是否滚动到底部的逻辑是关键,通常使用scrollTop + clientHeight >= scrollHeight - threshold(threshold为触发阈值)。
mounted() {
window.addEventListener('scroll', this.handleScroll);
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll);
},
methods: {
handleScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight;
const scrollHeight = document.documentElement.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 50) {
this.loadMore();
}
}
}
使用Intersection Observer API
现代浏览器支持IntersectionObserver,性能优于滚动事件监听。在页面底部放置一个哨兵元素(如<div id="sentinel"></div>),当其进入视口时触发加载。
data() {
return {
observer: null
};
},
mounted() {
this.observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
this.loadMore();
}
});
this.observer.observe(document.querySelector('#sentinel'));
},
beforeDestroy() {
this.observer.disconnect();
}
分页数据加载逻辑
在loadMore方法中实现分页请求,需注意避免重复请求和超出总页数的情况。典型实现包括页码递增和锁机制。
data() {
return {
page: 1,
loading: false,
hasMore: true
};
},
methods: {
async loadMore() {
if (this.loading || !this.hasMore) return;
this.loading = true;
try {
const res = await fetchData(this.page + 1); // 替换为实际API调用
if (res.data.length) {
this.list = [...this.list, ...res.data];
this.page++;
} else {
this.hasMore = false;
}
} finally {
this.loading = false;
}
}
}
使用第三方库
若需快速实现,可考虑以下库:
vue-infinite-loading:提供开箱即用的无限滚动组件vue-virtual-scroller:适用于长列表虚拟滚动vant/element-ui的InfiniteScroll指令
以vue-infinite-loading为例:
<template>
<div>
<div v-for="item in list" :key="item.id">{{ item }}</div>
<infinite-loading @infinite="loadMore" />
</div>
</template>
<script>
import InfiniteLoading from 'vue-infinite-loading';
export default {
components: { InfiniteLoading },
methods: {
loadMore($state) {
fetchData().then(res => {
if (res.data.length) {
this.list.push(...res.data);
$state.loaded();
} else {
$state.complete();
}
});
}
}
};
</script>
性能优化建议
- 对于长列表,结合虚拟滚动技术(如
vue-virtual-scroller)减少DOM节点 - 添加防抖(如
lodash.debounce)避免频繁触发 - 移动端考虑
touchmove事件替代scroll - 分页请求失败时提供重试机制
- 使用
keep-alive缓存已加载数据







