说明:
打开页面就立即去加载数据,效率低下<br />在页面很长时,位于底部的组件可能用户根本就不会到达,那这些组件的数据加载就是一种浪费
目标:
实现当组件进入可视区域之后才去发请求加载数据,没有进入可视区域时,ajax请求是不发的。<br /> (接管了由生命周期钩子函数发送的请求模式变成手动控制什么时候发起)
核心原理:
- 如何判断一个DOM元素是否进入了可视区域?
1.1 传统:
获取dom的位置,手动判断。(距离页面顶部的距离 比较 滚动条卷起的高度,还要考虑元<br /> 素自己的高度 )
1.2. 现在:
核心方法: useIntersectionObserver 帮助我们监听组件是否进入到视口区域 <br /> 直接判断元素进入可视区域的比例(使用第三方@vueuse/core中useIntersectionObserver) <br /> vueuse官网: https://vueuse.org/core/useIntersectionObserver/#usage
2. 进入可视区后:
2.1 停止观察<br /> 2.2 获取数据
固定代码:
我们在这个基础上进行功能的完成
const { stop } = useIntersectionObserver(
target, // 可以是由ref生成的组件实例对象 也可以是由ref生成的原生dom对象 也可以直接传入一个原生dom对象
([{ isIntersecting }], observerElement) => {
console.log(isIntersecting)
if (isIntersecting) {
// 进入就是true 出去就是false
// 在这里执行按需获取数据
}
},
{
// 用来控制目标target进入视口区域的比例
// 0 - 1 数值越大要求进入到视口区域的面积越大 才会触发回调
// 数值越小要求进入到视口区域的面积越小 才会触发回调
threshold: 0.1
}
)
使用步骤:
1. 安装引入:
没下载需要下载’@vueuse/core’)
import { useIntersectionObserver } from '@vueuse/core'
2. 通用逻辑封装
存在的问题: 每个地方发送请求都要进行数据懒加载的使用,那就会造成有很多重复的代码,所以可以封装成一个通用的数据懒加载的组件<br /> src/compositions/index.js
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
/**
* 功能: 数据懒加载
*
* @param {*} fn 当目标可见时,要调用一次的函数
* @returns target: 要观察的目标(vue3的引用)
*/
const useLazyData = (fn) => {
const target = ref(null)
// 1. stop 是一个函数。如果调用它,就会停止观察(是否进入或移出可视区域的行为)
// 2. target 是观察的目标容器 dom对象 | 组件对象
// 3. isIntersecting 是一个bool值,表示是否进入可视区域。 true表示 进入 false表示 移出
const { stop } = useIntersectionObserver(
target, // target 是vue的对象引用。是观察的目标
// isIntersecting 是否进入可视区域,true是进入 false是移出
// observerElement 被观察的dom
([{ isIntersecting }], observerElement) => {
// 在此处可根据isIntersecting来判断,然后做业务
if (isIntersecting) { // 目标可见,
// 1. ajax可以发了,后续不需要观察了
stop()
// 2. 执行函数
fn()
}
}
)
return target
}
export default useLazyData
3. 在组件中的使用:
说明: 在组件中发送请求的地方调用数据懒加载即可,举个例子<br />
3.1 在模板中:
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1626856779398-2c70b84c-504d-43c4-a6f0-cc07bc6e6ec6.png#clientId=u67e0881a-d1a8-4&from=paste&height=43&id=ua133a6f1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=86&originWidth=631&originalType=binary&ratio=1&size=23086&status=done&style=none&taskId=u9cd30069-94ba-4537-9f53-3628781f947&width=315.5)
3.2 代码实现:
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1626857176297-1d668fd1-3d0f-404a-9932-4210a7560799.png#clientId=u67e0881a-d1a8-4&from=paste&height=342&id=uc40c89a4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=683&originWidth=886&originalType=binary&ratio=1&size=171701&status=done&style=none&taskId=udc8a9294-1df3-4eae-8219-dc5a14ab7ff&width=443)
实现的效果就是:
不加数据懒加载就是, 页面一打开就调用所有请求,加载数据,效率低下, 现在就是, 只有当target这个目标出现在页面中的时候, 才去调用函数,加载数据
数据懒加载的