目标
了解如何实现图片数据懒加载
图片懒加载
背景
电商类网站,图片会非常的多,而如果一上来就加载所有的图片,会导致网页加载很慢
图片懒加载:等图片正式进入到可视区中时,才加载对应的图片,否则不请求图片
图片懒加载的原理:
如何知道图片进入或者离开了可视区?
通过vueuse封装的useIntersectionObserver
useIntersectionObserver
// 实时监听这个dom是否在可视区内
// const { stop } = useIntersectionObserver(要监视的dom, ([{ isIntersecting }]) => {
// // 回调函数: 当 isIntersecting 变化时:从可见->不可见; 不可见->可见
// isIntersecting: 当前是否可见?
// })
// stop: 停止监听
优化代码--封装自定义指令
封装指令 v-lazy,实现图片懒加载
/1.导入所有的公共组件
//2.定义插件,并导出
import { useIntersectionObserver } from '@vueuse/core';
import defaultImg from '@/assets/images/200.png'
import {App} from 'vue'
export default {
install(app:App){
app.directive('lazy',{
//mounted是v3自定义指令的生命周期,它会被自动调用
//它表示的含义和组件的mounted是一致的
//el是dom元素, binding
mounted(el,binding){
//设置默认图
el.src=defaultImg
// console.log('lazy',el,binding.value);
//实时监听el是否可见,如果可见,给他的src设置binding
const {stop} = useIntersectionObserver(el,([{isIntersecting}])=>{
if(isIntersecting){
el.src = binding.value
//停止
stop()
}
})
//el是img标签
//el.onerror 0级dom事件
el.onerror=()=>{
el.src = defaultImg
}
}
})
}
}
直接使用v-lazy,实现功能
数据懒加载
目标:封装组件数据懒加载可复用的逻辑
应用场景:
首页中,很多地方都应该使用组件数据懒加载这个功能,不管是哪个模块使用,下面代码都会重复书写.事实上,唯一可能会随着业务使用发生变化的是 ajax接口的调用
封装通用的懒加载数据api,传入参数是一个函数
import { useIntersectionObserver } from '@vueuse/core';
import { onMounted, ref } from 'vue';
export function useLazyData(fn:()=>void){
const target = ref(null)
//当整个区域处于可见状态时,才发送ajax
onMounted(()=>{
// 第一个参数:ref引用,获取DOM
// 第二个参数:回调,回调里面的参数 isIntersecting 会在参数一获取的 DOM 元素进入可视区域的时候监听并且为 true
const { stop } = useIntersectionObserver(target.value,([{isIntersecting}])=>{
//可见
if(isIntersecting){
//发起请求
fn()
//停止监听
stop()
}
})
})
return target
}
调用函数,实现功能