问题:页面过长,下面的图片不一定访问到,存在一定浪费。
解决方案:图片懒加载,仅当进入视口区,才发送请求显示图片。
全局指令
// 全局指令
app.directive('指令名称',{
mounted(el, binding){
// el:指令绑定的元素
// binding:绑定的表达式。binding.value为表达式的值
}
})
在入口文件main.js中,定义一个全局指令,第一个参数是指令名称,为 img-lazy,需要图片懒加载时,调用 v-img-lazy 实现。即 全局指令使用 v-指令名称 实现;第二个参数是一个钩子,钩子内的第一个参数是元素,第一个参数是绑定的表达式
判断是否进入视口
vueuse插件中提供 useIntersectionObserver 方法,用于判断元素是否进去视口区。
import { useIntersectionObserver } from '@vueuse/core'
const { stop } = useIntersectionObserver(
el,
([{ isIntersecting }]) => {
...
// el:监听的目标对象/元素
//isIntersecting: 是否进入视口区域
}
)
如果进入视口,发送图片资源请求。优化:重复监听
import { useIntersectionObserver } from '@vueuse/core'
const { stop } = useIntersectionObserver(
el, // 监听的目标对象/元素
([{ isIntersecting }]) => {
// 进入视口区域
if(isIntersecting){
el.src = binding.value
stop() // 停止监听
}
}
)
停止监听:由方法解构出 stop 方法,可用于在 第一次完成加载后,调用stop() 来停止监听。
测试 - 在组件中调用懒加载指令(全局指令)
模板中,使用 v-指令名 调用,如 v-img-lazy
<img v-img-lazy='i.picture' />
// <元素 v-指令名称='binding'>
优化:封装成插件
问题:逻辑书写位置不合理(在main.js中写逻辑)
解决:将懒加载指令封装成插件,main.js入口文件仅负责注册插件。
// src/directives/index.js中(插件中)
const directivePlugin = {
install(app){
... // 使用app实现懒加载指令
}
}
// main.js
import directivePlugin from '@/directives/index'
app.use(directivePlugin) // 注册插件
完整代码: