图片懒加载

图片懒加载

Vue中实现图片懒加载

在Vue中实现图片懒加载,主要有以下几种方法:

1. 使用Vue-Lazyload插件

安装插件
对于Vue 2,可以使用vue-lazyload插件:

1
npm i vue-lazyload@1.2.3 -S

对于Vue 3,应使用vue-lazyload-next

1
npm i vue-lazyload-next -S

注册插件
main.js中注册插件,并配置相关参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Vue 2
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
loading: 'xxx.png', // 懒加载默认加载图片
error: 'xxx.png', // 加载失败后加载的图片
preLoad: 1.3, // 预加载高度的比例
attempt: 3 // 尝试加载次数
})

// Vue 3
import VueLazyloadNext from 'vue-lazyload-next';
app.use(VueLazyloadNext, {
loading: 'xxx.png',
error: 'xxx.png',
preLoad: 1.3,
attempt: 3
});

使用插件
在组件中,使用v-lazy指令来实现图片懒加载:

1
2
3
4
5
<!-- 懒加载img标签 -->
<img v-lazy="imgUrl" />

<!-- 懒加载背景图片 -->
<div v-lazy:background-image="bgUrl"></div>

v-lazy指令接收一个字符串类型的值,表示图片的地址。如果是背景图片,需要在指令后加上:background-image修饰符。

2. 使用Intersection Observer API

实现懒加载
可以手动使用IntersectionObserver API来实现图片懒加载:

1
2
3
4
5
6
7
8
9
10
11
12
13
export const lazyLoad = {
mounted(el, binding) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
el.src = binding.value
observer.unobserve(el)
}
})
})
observer.observe(el)
}
}

img标签上使用v-lazy指令:

1
<img v-lazy="imageUrl" />

这种方式不依赖于任何外部库,完全使用原生JavaScript API实现懒加载。

3. VueUse库

使用useIntersectionObserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div ref="target">
<img v-if="isVisible" :src="props.src" :alt="props.alt">
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
const target = ref(null)
const isVisible = ref(false)
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }]) => {
if (isIntersecting) {
isVisible.value = true
stop()
}
}
)
</script>

这种方式利用了@vueuse/core库中的useIntersectionObserver函数来实现懒加载。

以上是Vue中实现图片懒加载的几种常见方法,可以根据项目需求和个人喜好选择合适的实现方式。

自定义监听器

有一定的防抖措施

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function lazyLoad() {
const images = document.querySelectorAll(".lazy");
const scrollTop = window.pageYOffset;
images.forEach((img) => {
if (img.offsetTop < window.innerHeight + scrollTop) {
img.src = img.dataset.src;
img.classList.remove("lazy");
}
});
}
let lazyLoadThrottleTimeout;
document.addEventListener("scroll", function () {
if (lazyLoadThrottleTimeout) clearTimeout(lazyLoadThrottleTimeout);
lazyLoadThrottleTimeout = setTimeout(lazyLoad, 20);
});
1
2
3
<!-- 占位符⽰例 -->
<div class="lazy-placeholder" style="background-color: #ddd;height: 500px;"</div <!-- ⽚⽰ -->
<img class="lazy" data- src="path/to/image.jpg" alt="预览图" />