方案汇总:
- ElementUI el-image lazy
- vue-lazyload
- Loading=“lazy”
- Intersection Observer API
- 滚动监听 scroll event
一、ElementUI el-image lazy
使用 ElementUI 的 el-image 组件,设置 lazy 属性,即可实现图片懒加载。
代码示例
<template>
<div class="box">
<el-image
class="lazy-load"
v-for="url in urls"
:key="url"
:src="url"
lazy
></el-image>
</div>
</template>
<script>
export default {
data() {
return {
urls: [
"https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
"https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg",
"https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg",
"https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg",
"https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg",
"https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg",
"https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg",
],
};
}
}
</script>
<style scoped>
.box {
display: flex;
flex-direction: column;
}
.lazy-load {
width: 300px;
height: 300px;
}
</style>
二、vue-lazyload
vue-lazyload 是一个 Vue.js 的插件,用于实现图片懒加载。
npm install vue-lazyload --save
注意:Vue2.x 需要安装
1.x
的版本,避免安装默认的3.0.0-rc.2
(仅支持 Vue3),否则会出现 v-lazy 指令找不到的问题
代码示例
import Vue from "vue";
import VueLazyload from "vue-lazyload";
Vue.use(VueLazyload, {
preLoad: 1.3, // 预加载距离控制,1.3表示元素距离可视区域还有1.3倍自身高度时开始加载
loading: "", // 占位图
error: "", // 加载失败的图
attempt: 1, // 失败重试次数
});
<img v-lazy="imageUrl" alt="description" />
三、Loading=“lazy”
HTML5 新增的属性,用于实现图片懒加载。
注意:距离视窗小于 1000px 时,图片就会被加载
代码示例
<template>
<div class="box">
<img
style="margin-bottom: 400px;"
class="lazy-load"
v-for="url in urls"
:key="url"
:src="url"
loading="lazy"
></el-image>
</div>
</template>
<script>
export default {
data() {
return {
// 相关代码
};
}
}
</script>
<style scoped>
.box {
display: flex;
flex-direction: column;
}
.lazy-load {
width: 300px;
height: 300px;
}
</style>
四、Intersection Observer API
使用浏览器原生 API
Intersection Observer
,可以监听元素是否进入可视区域,从而实现图片懒加载。
代码示例
<template>
<div class="box">
<img v-for="url in urls" :key="url" :data-src="url" class="lazy-load" />
</div>
</template>
<script>
export default {
data() {
return {
// ...相关代码
};
},
mounted() {
this.createLazyLoad();
}
methods: {
createLazyLoad() {
// 获取所有需要懒加载的图片
const lazyImages = document.querySelectorAll('.lazyload')
// 创建IntersectionObserver实例
const lazyLoadObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 图片进入视口
const img = entry.target
img.src = img.dataset.src
img.classList.remove('lazyload')
// 停止观察已加载的图片
observer.unobserve(img)
}
})
})
// 观察每个懒加载图片
lazyImages.forEach(img => lazyLoadObserver.observe(img))
}
}
};
</script>
五、滚动监听 scroll event
通过滚动监听事件手动判断图片是否进入视口,实现图片懒加载。
代码示例
<template>
<img class="lazy-load" v-for="url in urls" :key="url" :data-src="url" />
</template>
<script>
export default {
data() {
return {
// 相关代码
throttleHandler: null, // 存储节流函数,便于销毁监听事件
};
},
created() {
this.trottleHandler = this.throttle(this.createScrollLazyLoad, 100);
this.createScrollLazyLoad(); // 首次手动触发,确保图片加载
window.addEventListener("scroll", this.trottleHandler); // 使用节流函数提升性能
},
methods: {
throttle(fn, delay) {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn.apply(this, arguments);
}, delay);
}
};
},
createScrollLazyLoad() {
document.querySelectorAll("img[data-src]").forEach((img) => {
const rect = img.getBoundingClientRect();
console.log(rect);
if (rect.top < window.innerHeight) {
img.src = img.dataset.src;
img.removeAttribute("data-src");
}
});
},
},
beforeDestroy() {
window.removeEventListener("scroll", this.trottleHandler); // 使用节流函数提升性能
},
};
</script>
优缺点及使用场景对比
方案 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
ElementUI el-image lazy | 使用 ElementUI 的 el-image 组件,设置 lazy 属性,即可实现图片懒加载。 | 依赖于 ElementUI 组件库 | 适用于 ElementUI 项目 |
vue-lazyload | 轻量级,简单易用 | 需要添加额外的依赖 | 适用于需快速集成的复杂项目 |
Loading=“lazy” | HTML5 新增的属性,配置简单。 | 距离视窗小于 预加载阈值(1000px) 时,图片就会被加载;存在兼容性问题;无法自定义加载逻辑 | 简单场景,兼容性要求低的项目 |
Intersection Observer | 不依赖库,性能较好 | 需处理浏览器兼容性 | 适用于运行在现代浏览器的项目 |
滚动监听 scroll event | 兼容性好,支持自定义加载逻辑 | 代码复杂,需考虑首次加载、性能等问题 | 适用于需要高度定制加载逻辑的场景 |