大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说组件数据懒加载(vue3),希望您对编程的造诣更进一步.
1、何为组件数据懒加载?
前言
电商项目核心优化技术手段:组件数据懒加载 (首屏渲染优化)
电商类网站,首页内容有好几屏,如果一上来就加载所有屏的数据,并渲染所有屏的内容,必然发送很多次无效的请求,我们应该等所在模块进入到 可视区
再发请求获取数据。
思考
- 我们一般的数据请求在哪里发起?
setup
(created) - 生命周期钩子函数的特点是什么? 一加载组件,就立刻执行
结论
我们希望组件正式进入到 可视区
中时,才把组件内部的 ajax
请求发起,否则不请求数据,那如何判断进入可视区,并进行组件数据懒加载呢?
2、如何判断组件进入可视区?
技术方案
我们可以使用 @vueuse/core
中的 useIntersectionObserver来实现监听组件进入可视区域行为, 需要配合 vue3.0
的组合 API
的方式才能实现
分析useIntersectionObserver
函数:
// 下包 npm i @vueuse/core@5.3.0 或 yarn add @vueuse/core@5.3.0
// 导入 useIntersectionObserver 函数
import { useIntersectionObserver } from '@vueuse/core'
// 1.stop 一个可执行的函数用来停止监听行为
// 2.target 一个由 ref api 调用之后形成的 RefImpl 对象 也可以是一个 dom 对象
// 3.isIntersecting 一个类型为布尔值的数据 当被监听元素进入视口区域时为 true ,离开视口区域时为 false
// 4.observerElement 被观察的dom
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
targetIsVisible.value = isIntersecting
}
)
// ◆特别注意: 对于目标target是否进入视口区域的监听会一直进行不会只监听一次,可以 stop() 关闭监听
3、实现组件数据懒加载(代码落地)
- 通过
ref
属性获得组件实例并测试 - 使用
useIntersectionObserver
监听函数 - 发送的ajax请求在
isIntersecting
为true
时触发 - 一旦触发一次之后停止监听
stop()
,防止接口重复调用
<template>
<HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过"> <ul class="goods-list"> <li v-for="item in hotList" :key="item.id"> <RouterLink to="/"> <img :src="item.picture" alt=""> <p class="name">{{item.title}}</p> <p class="desc">{{item.alt}}</p> </RouterLink> </li> </ul> </HomePanel> </template>
<script> // 导入子组件 HomePanel import HomePanel from './home-panel' // 导入获取数据的件接口函数 import { reqFindHot } from '@/api/home' // 导入 ref 函数(使目标数据变成响应式数据) import { ref } from 'vue' // 导入 useIntersectionObserver 进行监听 import { useIntersectionObserver } from '@vueuse/core' export default { name: 'HomeHot', components: { HomePanel },// 注册子组件 setup () { const hotList = ref([]) const getHotList = async () => { const res = await reqFindHot() hotList.value = res.result } // getHotList() // 1.通过 ref 获得组件实例 const target = ref(null) // 2.使用 useIntersectionObserver 监听函数 const { stop } = useIntersectionObserver( target,// 3.target 是被观察的目标dom容器 ([{ isIntersecting }], observerElement) => { // 4.在此处可根据 isIntersecting 来判断,然后做处理 console.log(isIntersecting) // 5.如果 isIntersecting 为 true if (isIntersecting) { stop()// 6.中止监听 getHotList()// 7.调用函数(发送请求) } } ) // 8.把 target 返回 return { hotList, target} } } </script>
4、组件数据懒加载的逻辑复用
事实上,首页中有很多地方都应该使用 组件数据懒加载 这个功能,不管是哪个模块使用,下面代码都会重复书写,可能会随着业务使用发生变化的是 ajax
接口的调用,其余的部分我们进行重复使用,抽离为可复用逻辑。
下面,我们将以上代码抽离出来进行复用:
新建 src/compositions/index.js
// ◆封装组件懒加载的函数
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
// 按需导出
export function useObserver (apiFn) {// apiFn 为形参
const target = ref(null)
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
console.log(isIntersecting, '666')
if (isIntersecting) {
stop()// 终止监听
apiFn && apiFn()
}
}
)
return target// 一定要 return 出去
}
在需要的页面调用
<template>
<HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过"> <ul class="goods-list"> <li v-for="item in hotList" :key="item.id"> <RouterLink to="/"> <img :src="item.picture" alt=""> <p class="name">{{item.title}}</p> <p class="desc">{{item.alt}}</p> </RouterLink> </li> </ul> </HomePanel> </template>
<script> import HomePanel from './home-panel' import { reqFindHot } from '@/api/home' import { ref } from 'vue' // import { useIntersectionObserver } from '@vueuse/core' // 1.按需导入封装好的组件懒加载函数 import { useObserver } from '@/compositions' export default { name: 'HomeHot', components: { HomePanel }, setup () { const hotList = ref([]) const getHotList = async () => { const res = await reqFindHot() hotList.value = res.result } // 2.调用封装好的函数,传实参过去 const target = useObserver(getHotList) // getHotList() return { hotList, target } } } </script>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13351.html