电商类网站,图片会非常的多,而如果一上来就加载所有的图片,会导致网页加载很慢 图片懒加载的原理就是把图片的真实路径绑定给一个以data开头的自定义属性data-url即可,页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片(没有请求就提高了性能)等图片正式进入到可视区中时,才加载对应的图片,否则不请求图片
那么, 问题来了 如何知道图片进入或者离开了可视区?
传统方法: 滚动监听 获取可视窗口的大小 计算 scrollTop+offsetTop+innerHeight,再判断是否进入可视区,当出现在可视区请求正确的图片地址就好了,这个方法虽然能够实现图片懒加载,但需要自己手动去计算,相对比较麻烦
现在给大家分享一个 利用第三方库实现懒加载的方法
安装
@vueuse/core 函数库,它封装了常见的一些交互逻辑
npm i @vueuse/core
yarn add @vueuse/core
使用
用 useIntersectionObserver(),来实现监听进入可视区域行为
import { useIntersectionObserver } from '@vueuse/core'
// 实时监听这个dom是否在可视区内
const { stop } = useIntersectionObserver(要监视的dom, ([{ isIntersecting }]) => {
// // 回调函数: 当 isIntersecting 变化时:从可见->不可见; 不可见->可见
// isIntersecting: 当前是否可见?
})
// stop: 停止监听
由于懒加载在多个地方都会用到,所以我们可以封装成自定义指令,使用的时候 只需要把 img src 改成自定义指令即可~
// 自定义指令
import { useIntersectionObserver } from '@vueuse/core'
import { App } from 'vue'
import defaultImg from '@/assets/images/200.png' //默认加载图片
export default {
install(app: App) {
// 全局指令
// lazy ====> v-lazy
app.directive('lazy', {
// mounted是v3中自定义指令的生命周期,它会被自动调用
// 它表示的涵义和组件的mounted是一致的
// el 是dom元素, binding
mounted(el,binding) {
// 设置默认图
el.src = defaultImg
// console.log('lazy', el, binding.value)
// 实时监听el是否可见,如果可见,给他的src设置binding.value
const { stop } = useIntersectionObserver(el, ([{isIntersecting}]) => {
if(isIntersecting) {
el.src = binding.value
// 停止
stop()
}
})
// el是img标签
// el.onerror 0级dom事件
// el.onclick = () =>
// el.addEventListener('click')
// el.onerror = () => {
// }
el.addEventListener('error', () => {
// console.log('失败11111')
// 设置默认图
el.src = defaultImg
})
}
})
}
}