vue滚动加载实现
vue滚动加载实现
滚动加载是一种常见的优化手段,通过监听滚动事件动态加载数据,减少初始渲染压力。以下是几种实现方式:
使用IntersectionObserver API
IntersectionObserver是现代浏览器提供的API,性能优于传统滚动事件监听。
// 在组件中
data() {
return {
observer: null,
isLoading: false,
items: [],
page: 1
}
},
mounted() {
this.observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting && !this.isLoading) {
this.loadMore()
}
})
this.observer.observe(this.$refs.observerElement)
},
methods: {
async loadMore() {
this.isLoading = true
const newItems = await fetchData(this.page++)
this.items.push(...newItems)
this.isLoading = false
}
}
模板部分需要添加观察元素:
<div v-for="item in items">{{ item.content }}</div>
<div ref="observerElement" v-if="!isLoading && hasMore">Loading...</div>
使用滚动事件监听
传统方法通过计算滚动位置实现:
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const windowHeight = document.documentElement.clientHeight
const scrollHeight = document.documentElement.scrollHeight
if (scrollTop + windowHeight >= scrollHeight - 100 && !this.isLoading) {
this.loadMore()
}
}
}
使用第三方库
vue-infinite-loading是流行的滚动加载组件:
安装:
npm install vue-infinite-loading
使用:
import InfiniteLoading from 'vue-infinite-loading'
export default {
components: { InfiniteLoading },
methods: {
async loadMore($state) {
try {
const newItems = await fetchData(this.page++)
if (newItems.length) {
this.items.push(...newItems)
$state.loaded()
} else {
$state.complete()
}
} catch (e) {
$state.error()
}
}
}
}
模板:
<infinite-loading @infinite="loadMore">
<div slot="no-more">No more data</div>
<div slot="no-results">No results</div>
</infinite-loading>
性能优化建议
- 使用防抖函数避免频繁触发
- 添加加载状态锁防止重复请求
- 服务端应支持分页查询
- 移动端考虑使用IntersectionObserver
- 列表项添加key属性提高diff效率
以上方法可根据具体需求选择,现代浏览器推荐优先使用IntersectionObserver方案。







