组件数据懒加载(数据懒加载原理)
我们可以使用 @vueuse/core
中的 useIntersectionObserver
来实现监听进入可视区域行为,但是必须配合vue3.0的组合API的方式才能实现。
大致步骤:
理解
useIntersectionObserver
的使用,各个参数的含义改造 home-new 组件成为数据懒加载,掌握
useIntersectionObserver
函数的用法封装
useLazyData
函数,作为数据懒加载公用函数把
home-new
和home-hot
改造成懒加载方式
落的代码:
先分析下这个
useIntersectionObserver
函数:
// stop 是停止观察是否进入或移出可视区域的行为 const { stop } = useIntersectionObserver( // target 是观察的目标dom容器,必须是dom容器,而且是vue3.0方式绑定的dom对象 target, // isIntersecting 是否进入可视区域,true是进入 false是移出 // observerElement 被观察的dom ([{ isIntersecting }], observerElement) => { // 在此处可根据isIntersecting来判断,然后做业务 }, )复制代码
开始改造
home-new
组件:rc/views/home/components/home-new.vue
进入可视区后获取数据
<HomePanel ref="target" title="新鲜好物" subTitle="新鲜出炉 品质靠谱"> // 省略。。。 <script> import HomePanel from './home-panel' import HomeSkeleton from './home-skeleton' import { findNew } from '@/api/home' import { ref } from 'vue' import { useIntersectionObserver } from '@vueuse/core' export default { name: 'HomeNew', components: { HomePanel, HomeSkeleton }, setup () { const goods = ref([]) const box = ref(null) const { stop } = useIntersectionObserver( box, ([{ isIntersecting }]) => { if (isIntersecting) { stop() findNew().then(data => { goods.value = data.result }) } } ) return { goods, box } } } </script>复制代码
由于首页面板数据加载都需要实现懒数据加载,所以封装一个钩子函数,得到数据。
src/hooks/index.js
// hooks 封装逻辑,提供响应式数据。 import { useIntersectionObserver } from '@vueuse/core' import { ref } from 'vue' // 数据懒加载函数 export const useLazyData = (apiFn) => { // 需要 // 1. 被观察的对象 // 2. 不同的API函数 const target = ref(null) const result = ref([]) const { stop } = useIntersectionObserver( target, ([{ isIntersecting }], observerElement) => { if (isIntersecting) { stop() // 调用API获取数据 apiFn().then(data => { result.value = data.result }) } } ) // 返回--->数据(dom,后台数据) return { target, result } }复制代码
再次改造
home-new
组件:rc/views/home/components/home-new.vue
import { findNew } from '@/api/home' +import { useLazyData } from '@/hooks' export default { name: 'HomeNew', components: { HomePanel, HomeSkeleton }, setup () { + const { target, result: goods } = useLazyData(findNew) + return { goods, target } } }复制代码
+ <HomePanel ref="target" title="新鲜好物" subTitle="新鲜出炉 品质靠谱">复制代码
然后改造
home-hot
组件:src/views/home/components/home-hot.vue
+ <HomePanel ref="target" title="人气推荐" subTitle="人气爆款 不容错过">复制代码
import { findHot } from '@/api/home' import HomePanel from './home-panel' import HomeSkeleton from './home-skeleton' +import { useLazyData } from '@/hooks' export default { name: 'HomeHot', components: { HomePanel, HomeSkeleton }, setup () { + const { target, result: goods } = useLazyData(findHot) + return { target, goods } } }
作者:jiujue
链接:https://juejin.cn/post/7032542074918404132