一、熟悉指令语法
在 main.js 中定义全局指令
// 定义全局指令
app.directive('img-lazy', {
mounted(el, binding) {
// el:指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片 url
console.log(el, binding.value);
}
})
二、判断图片是否进入视口,这里用vueUse中的方法
useIntersectionObserver | VueUse
在 main.js 中修改代码
import { useIntersectionObserver } from '@vueuse/core'
// 定义全局指令
app.directive('img-lazy', {
mounted(el, binding) {
// el:指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片 url
console.log(el, binding.value);
useIntersectionObserver(
el,
([{ isIntersecting }],) => {
console.log(isIntersecting);
},
)
}
})
三、测试图片监控知否生效
// 定义全局指令
app.directive('img-lazy', {
mounted(el, binding) {
// el:指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片 url
console.log(el, binding.value);
useIntersectionObserver(
el,
([{ isIntersecting }],) => {
// console.log(isIntersecting);
if (isIntersecting) {
el.src = binding.value
}
},
)
}
})
四、优化懒加载指令
4.1 位置优化
将懒加载指令放在 main.js 入口文件中十分不合理,因此可以将懒加载包装成一个插件
在src文件中新建文件夹directives->index.js
// 定义懒加载插件
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin = {
install(app) {
// 懒加载指令逻辑
// 定义全局指令
app.directive('img-lazy', {
mounted(el, binding) {
// el:指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片 url
console.log(el, binding.value);
useIntersectionObserver(
el,
([{ isIntersecting }],) => {
// console.log(isIntersecting);
if (isIntersecting) {
el.src = binding.value
}
},
)
}
})
}
}
在 main.js 中引入懒加载指令插件并且注册
import { lazyPlugin } from '@/directives/index.js'
// 注册懒加载指令
app.use(lazyPlugin)
4.2 问题2:重复监听问题
useIntersectionObserver对于元素的监听是一直存在的,除非手动停止监听,存在内存浪费
解决思路:在监听的图片第一次完成加载之后就停止监听