可以使用到VueUse 这个工具辅助
图片懒加载的原理:
在图片未进入可视区域时,不给 src 属性赋值,这样浏览器就不会发送请求。当图片进入可视区域时,再给 src 属性赋值,从而发起请求加载图片。
VueUse useIntersectionObserver 可以用来判断元素是否在可见范围内
使用案例
<script setup>
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
const target = ref(null)
const targetIsVisible = ref(false)
const { stop } = useIntersectionObserver(
target,
([entry], observerElement) => {
targetIsVisible.value = entry?.isIntersecting || false
},
)
</script>
<template>
<div ref="target">
<h1>Hello world</h1>
</div>
</template>
使用步骤:
1.需要在项目中新建一个文件夹 directives 用来存在指令,创建一个index.js 文件
//引入 VueUse 里面的指令
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin={
// 获取app实例
install(app){
//懒加载指令的实现
app.directive('img-lazy',{
// el:能够获取到绑定的元素 等同于 ref 绑定的元素 binding:传递过来的参数
mounted(el,binding){
// 通过解构赋值 获取到 stop 方法,在滚动到指定位置后,关闭监听的方法,
// 否则非常浪费性能 滚动的时候会一直执行,实际上,第一次滚动到该位置
// 渲染完成后就不需要进行监听该事件
const { stop } = useIntersectionObserver(
el,
([{isIntersecting}]) => {
// 是否在可视区域内
if(isIntersecting){
// 如果在可视区域内,将获取到的路径值赋值给src
el.src=binding.value
// 获取到值后关闭 监听
stop()
}
},
)
}
})
}
}
2.在main.js 中进行全局挂载
// 引入懒加载指令插件并注册
import { lazyPlugin} from '@/directives'
const app=createApp(App)
app.use(lazyPlugin)
app.mount('#app')
3.在需要使用到的地方用
<template>
<HomePanel title="新鲜好物" sub-title="新鲜出炉 品质靠谱">
<ul class="goods-list">
<li v-for="item in newList" :key="item.id">
<RouterLink to="/">
// 传入 照片的路径
<img v-img-lazy="item.picture" alt="" />
<p class="name">{{ item.name }}</p>
<p class="price">¥{{ item.price }}</p>
</RouterLink>
</li>
</ul>
</HomePanel>
</template>