Vue3实现高效图片懒加载与预加载策略详解
一、图片懒加载的基本概念
二、Vue3中的图片懒加载实现
1. 使用VueUse库实现懒加载
步骤如下:
- 安装VueUse库
npm install @vueuse/core
- 定义懒加载指令
import { useIntersectionObserver } from '@vueuse/core';
export default {
directives: {
lazy: {
mounted(el, binding) {
const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = binding.value;
stop();
}
});
}
}
}
};
- 在组件中使用懒加载指令
<img v-lazy="imageSrc" alt="Lazy Image">
2. 手动实现懒加载指令
如果不希望依赖第三方库,也可以手动实现一个懒加载指令。
步骤如下:
- 定义懒加载指令
export default {
directives: {
lazy: {
mounted(el, binding) {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
el.src = binding.value;
observer.unobserve(el);
}
}, {
threshold: 0.1
});
observer.observe(el);
}
}
}
};
- 在组件中使用懒加载指令
<img v-lazy="imageSrc" alt="Lazy Image">
三、图片预加载策略
1. 预加载hover状态图片
示例代码:
<script setup>
import { ref, onMounted } from 'vue';
const hoverImageSrc = ref('');
const defaultImageSrc = ref('');
onMounted(() => {
const hoverImg = new Image();
hoverImg.onload = () => {
hoverImageSrc.value = hoverImg.src;
};
hoverImg.src = 'path/to/hover-image.jpg';
const defaultImg = new Image();
defaultImg.onload = () => {
defaultImageSrc.value = defaultImg.src;
};
defaultImg.src = 'path/to/default-image.jpg';
});
</script>
<template>
<img :src="defaultImageSrc" @mouseover="hoverImageSrc" @mouseout="defaultImageSrc" alt="Preloaded Image">
</template>
2. 使用Vue指令预加载图片
示例代码:
export default {
directives: {
preload: {
mounted(el, binding) {
const img = new Image();
img.onload = () => {
el.src = binding.value;
};
img.src = binding.value;
}
}
}
};
在组件中使用预加载指令:
<img v-preload="imageSrc" alt="Preloaded Image">
四、结合懒加载与预加载的综合策略
在实际应用中,往往需要结合懒加载和预加载策略,以达到最佳的性能和用户体验。以下是一个综合示例:
示例代码:
<script setup>
import { ref, onMounted } from 'vue';
const imageSrc = ref('');
const preloadImages = ['path/to/image1.jpg', 'path/to/image2.jpg'];
onMounted(() => {
preloadImages.forEach((imgSrc) => {
const img = new Image();
img.onload = () => {
console.log(`Preloaded: ${imgSrc}`);
};
img.src = imgSrc;
});
});
</script>
<template>
<div>
<img v-lazy="imageSrc" alt="Lazy Image">
<img v-preload="preloadImages[0]" alt="Preloaded Image 1">
<img v-preload="preloadImages[1]" alt="Preloaded Image 2">
</div>
</template>