自定义指令实现图片懒加载
步骤:
- 自定义指令
- 判断图片是否进入视口
- 只有进入视口的图片才发送网络请求
- 代码优化
自定义指令
main.js
app.directive('img-lazy', {
mounted(el,binding) {
// el是绑定的img元素,binding.value是图片src
console.log(el, binding.value)
}
})
绑定元素:
<img v-img-lazy="item.picture" :src="item.picture" alt=""/>
判断图片是否进入视口
直接使用 vueuse 的 useIntersectionObserver 方法:useIntersectionObserver 。
main.js
import { useIntersectionObserver } from '@vueuse/core'
app.directive('img-lazy', {
// 挂载完毕
mounted(el,binding) {
console.log(el, binding.value)
// 监听 el 元素,isIntersecting 判断是否进入视口区域
useIntersectionObserver(
el,
([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = binding.value
}
},
)
}
})
绑定元素:
通过自定义指令来发送图片网络请求。
<img v-img-lazy="item.picture" alt=""/>
代码优化
封装自定义懒加载插件
import {useIntersectionObserver} from "@vueuse/core";
/**
* 自定义懒加载插件
* @type {{install(*): void}}
*/
export const lazyPlugin = {
install(app) {
app.directive('img-lazy', {
mounted(el,binding) {
useIntersectionObserver(
el,
([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = binding.value
}
},
)
}
})
},
}
入口文件注册:
import {lazyPlugin} from "@/directives/index.js";
app.use(lazyPlugin)
禁止重复监听
useIntersectionObserver 中存在一个 stop 方法。通过请求图片资源后调用该方法可以实现禁止重复监听。
export const lazyPlugin = {
install(app) {
app.directive('img-lazy', {
mounted(el,binding) {
const {stop} = useIntersectionObserver(
el,
([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = binding.value
stop()
}
},
)
}
})
},
}