实现图片懒加载
- 自定义指令
<template>
<div class="box">
<div>
<img v-lazy="item" alt="" v-for="(item, index) in arr" :key="index" style="width:400px; height:300px">
</div>
</div>
</template>
<script setup lang='ts'>
import { Directive } from 'vue';
let vLazy: Directive<HTMLImageElement, string> = async (el, binding) => {
let defaultImage = await import('./assets/defaultImage/vue.svg') // 默认图片
el.src = defaultImage.default
observer.observe(el)
}
- 引入图片
import.meta.glob的官方文档,globEager已经废弃。
<script setup lang='ts'>
import { Directive } from 'vue';
let imageList: Record<string, { default: string }> = import.meta.globEager('./assets/image/*.*')
let arr = Object.values(imageList).map(v => { return v.default })
</script>
- js 的 IntersectionObserver API
官方文档,这里主要用到的是IntersectionObserverEntry.intersectionRatio ,用于检测当前在根的交叉比中有多少目标元素可见,值介于0.0和1.0之间。


<script setup lang='ts'>
import { Directive } from 'vue';
let imageList: Record<string, { default: string }> = import.meta.globEager('./assets/image/*.*')
let arr = Object.values(imageList).map(v => { return v.default })
let vLazy: Directive<HTMLImageElement, string> = async (el, binding) => {
let defaultImage = await import('./assets/defaultImage/vue.svg')
el.src = defaultImage.default
const observer = new IntersectionObserver((entry) => {
if (entry[0].intersectionRatio > 0) {
setTimeout(() => {
el.src = binding.value
observer.unobserve(el)
}, 1000)
}
})
observer.observe(el)
}
</script>