前言:电商类网站的图片非常多,很有必要做一下图片懒加载,把网络性能优化做到 极致!
- 实现步骤:
vue3全局指令的定义方式app.directive,- 以插件的形式注册全局指令
- 编写懒加载指令的具体逻辑
// vue2
Vue.directive(指令名, {
inserted (el, binding) {
}
})
// vue3
app.directive(指令名, {
// 指令所在的元素,dom结构被解析完成
mounted (el, binding) {
}
})
1、新建src/directive/index.js,编写指令逻辑
// 导入默认图片
import defaultImg from '@/assets/images/01.png'
// 引入监听是否进入视口
import { useIntersectionObserver } from '@vueuse/core'
export default {
// 需要拿到 main.js 中由 createApp 方法产出的 app 实例对象
install (app) {
// app 实例身上有我们想要的全局注册指令方法 调用即可
app.directive('lazyImg', {
mounted (el, binding) {
// el:img dom对象
// binding.value 图片url地址
// 使用 vueuse/core 提供的监听 api 对图片 dom 进行监听 正式进入视口才加载
// img.src = url
console.log(el, binding)
const { stop } = useIntersectionObserver(
// 监听目标元素
el,
([{ isIntersecting }], observerElement) => {
if (isIntersecting) {
// ◆图片加载失败显示默认图片
el.onerror = function () {
el.src = defaultImg
}
// ◆这里显示传过来的图片数据
el.src = binding.value
stop()// 中止监听
}
})
}
})
}
}
2、main.js 里面导入自定义的全局图片懒加载指令,并注册插件
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// ◆导入 图片懒加载指令
import imgPlugin from './directives'
// ◆链式编程:createApp.use(imgPlugin)
createApp(App).use(imgPlugin).use(store).use(router).mount('#app')
3、在需要的页面,使用 v-lazyImg 指令
<template>
<HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过">
<ul class="goods-list">
<li v-for="item in hotList" :key="item.id">
<RouterLink to="/">
<!-- <img :src="item.picture" alt=""> -->
<!--◆ 使用自定义图片懒加载指令 -->
<img v-lazyImg="item.picture" alt="">
<p class="name">{{item.title}}</p>
<p class="desc">{{item.alt}}</p>
</RouterLink>
</li>
</ul>
</HomePanel>
</template>
打开
network下的img请求,慢慢滚动页面,会发现图片不是一次性加载出来的,这就实现了图片懒加载