数据懒加载是一个不可避免要解决的事情 Vue3中又提供了什么方法来解决呢
使用 @vueuse/core 中的 useIntersectionObserver 来实现监听进入可视区域行为,配合vue3.0的组合API的方式实现。
- 这是
useIntersectionObserver函数:
// const {stop} = useIntersectionObserver(target, fn, options)
// 1、参数一target表示被监听的DOM元素
// 2、参数二是回调函数,用于通知监听的动作(回调函数的第一个形参isIntersecting表示被监听的元素已经进入了可视区)
// 3、表示配置选项
// stop 是停止观察是否进入或移出可视区域的行为
const { stop } = useIntersectionObserver(
// target 是观察的目标dom容器,必须是dom容器,而且是vue3.0方式绑定的dom对象
target,
// isIntersecting 是否进入可视区域,true是进入 false是移出
// observerElement 被观察的dom
([{ isIntersecting }], observerElement) => {
// 在此处可根据isIntersecting来判断,然后做业务
},
)
具体步骤
1.1这是具体的实现代码 可以封装成一个单独的文件 需要的时候直接导入
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
// 封装一个Hook方法实现数据懒加载
export const useLazyData = (apiFn) => {
// 当前组件进入可视区时触发接口调用
// 被监听的DOM元素
const target = ref(null)
// 调用接口获取的结果
const result = ref([])
const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) => {
if (isIntersecting) {
// 进入可视区
apiFn().then(data => {
result.value = data.result
})
// 停止监听
stop()
}
})
return { result, target }
}
2.需要的组件中直接使用
- 哪个部分需要 加一个
ref="target"
- 导入刚才的文件
import { useLazyData } from '@/hook' - 直接使用
2.1有一个小问题:
如果需要懒加载的组件面积比较大,页面需要滚动比较多的面积才回去加载数据,效果不好。
2.2原因:
useIntersectionObserver 默认以进入视口的面积占总元素面积的0.1为基准判断是否进入,而这里的默认比例0.1在元素比较大的时候,会有这个问题:看起来已经可见了,但是我们回调没有执行。
2.2 解决:
补充一个参数:threshold ,容器和可视区交叉的占比(进入的面积/容器完整面积) 取值,直接取0
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }]) => {
if (isIntersecting) {
stop()
apiFn()
}
},
{ threshold: 0}
)
return { result, target }
}