vue实现列表懒加载
vue实现列表懒加载的方法
使用IntersectionObserver API
IntersectionObserver API可以监听元素是否进入视口,适合实现懒加载。在Vue中可以通过自定义指令或组件实现。
// 自定义指令实现
Vue.directive('lazy', {
inserted: (el, binding) => {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
binding.value()
observer.unobserve(el)
}
})
})
observer.observe(el)
}
})
// 组件中使用
<template>
<div v-lazy="loadMore">加载更多...</div>
</template>
使用第三方库vue-lazyload
vue-lazyload是专门为Vue设计的懒加载库,支持图片和组件懒加载。

import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preLoad: 1.3,
attempt: 3
})
// 使用方式
<img v-lazy="imageUrl">
滚动事件监听实现
通过监听滚动事件计算元素位置,判断是否需要加载。

methods: {
handleScroll() {
const scrollBottom = window.innerHeight + window.scrollY
const elementTop = this.$refs.loadMore.getBoundingClientRect().top + window.scrollY
if (scrollBottom > elementTop - 100) {
this.loadMore()
}
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
}
无限滚动组件实现
封装可复用的无限滚动组件,适用于分页加载场景。
<template>
<div class="infinite-scroll" @scroll="onScroll">
<slot></slot>
<div v-if="loading" class="loading">加载中...</div>
</div>
</template>
<script>
export default {
props: {
loading: Boolean,
distance: {
type: Number,
default: 50
}
},
methods: {
onScroll(e) {
const { scrollTop, scrollHeight, clientHeight } = e.target
if (scrollHeight - (scrollTop + clientHeight) < this.distance && !this.loading) {
this.$emit('load-more')
}
}
}
}
</script>
虚拟滚动优化性能
对于超长列表,使用虚拟滚动技术只渲染可见区域元素。
// 使用vue-virtual-scroller
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
components: {
RecycleScroller
}
<template>
<RecycleScroller
class="scroller"
:items="list"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div class="item">{{ item.text }}</div>
</RecycleScroller>
</template>
每种方法适用于不同场景,IntersectionObserver API最现代且性能最好,vue-lazyload适合图片懒加载,滚动事件监听兼容性最好,无限滚动组件适合分页加载,虚拟滚动适合超长列表优化性能。






