vue2实现图片懒加载
使用 Intersection Observer API
Intersection Observer API 是浏览器原生支持的 API,用于监听目标元素与视口的交叉状态。创建一个观察器实例,配置回调函数和选项(如阈值、根元素等)。当目标图片进入视口时,将 data-src 属性替换为 src 属性。
// 创建观察器实例
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, {
rootMargin: '0px 0px 100px 0px' // 提前100px触发加载
});
// 对所有懒加载图片进行观察
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
自定义指令实现
Vue 2 支持自定义指令,可以封装懒加载逻辑为全局指令 v-lazy。在指令的 inserted 钩子中绑定观察器,当元素进入视口时动态修改 src。
// main.js 或单独指令文件
Vue.directive('lazy', {
inserted: (el, binding) => {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
el.src = binding.value;
observer.unobserve(el);
}
});
observer.observe(el);
}
});
// 模板中使用
<img v-lazy="imageUrl" alt="Lazy Image">
兼容旧浏览器的滚动监听
对于不支持 Intersection Observer 的浏览器(如 IE),可通过监听滚动事件实现。计算图片位置与视口的关系,手动触发加载。
function lazyLoad() {
const images = document.querySelectorAll('img[data-src]');
images.forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight + 100) {
img.src = img.dataset.src;
}
});
}
// 初始化加载 + 滚动监听
window.addEventListener('scroll', lazyLoad);
window.addEventListener('load', lazyLoad);
使用第三方库
现有库如 vue-lazyload 提供了开箱即用的解决方案,支持占位图、错误处理等高级功能。安装后通过 Vue 插件形式集成。

npm install vue-lazyload
import VueLazyload from 'vue-lazyload';
Vue.use(VueLazyload, {
preLoad: 1.3, // 预加载比例
error: 'error.png', // 错误占位图
loading: 'loading.gif', // 加载中占位图
attempt: 3 // 重试次数
});
// 模板中使用
<img v-lazy="imageUrl" alt="Lazy Image">
性能优化建议
设置合适的触发阈值(如 rootMargin)避免频繁计算。对已加载的图片取消观察(unobserve)。使用 loading="lazy" 原生属性作为降级方案(需注意浏览器兼容性)。






