VUE3------懒加载(图片、组件)
提示:提高加载速度,优化性能。文章目录
VUE3------懒加载(图片、组件)前言一、组件懒加载1.使用场景2.基础思路3.技术实现 二、图片懒加载1.使用场景2.基础思路3.技术实现具体落地: 全局指令的形式 三、避坑前言
懒加载:图片懒加载、组件懒加载、路由懒加载等等............一、组件懒加载
1.使用场景
如果页面很长 位于第一屏之外的组件用户可能根本没有机会看到 这类组件没有必要一上来就加载数据
2.基础思路
监听组件是否已经进入到视口区域 只有进入之后才正式发起网络请求(不再由生命周期钩子函数决定)
3.技术实现
1. 如何知道组件进入视口区域 useIntersectionObserver() 2. 在达到条件之后 发送ajax请求3. 在首次数据加载之后立刻结束监听
export function useObserver (apiFn) {// 监听的目标对象const target = ref(null)// stop 是一个可执行的方法 调用就会停止监听// 不管元素进入还是离开视口区域都不会再执行回调函数// 注意:不会只监听一次 只有进入视口或者离开视口回调函数都会执行const {stop } = useIntersectionObserver(// 监听目标元素target,([{isIntersecting }], observerElement) => {// isIntersecting 布尔值 代表当前监听的元素是否进入视口区域console.log(isIntersecting)// ...判断 一旦为true 就发送ajaxif (isIntersecting) {// 发起网络请求apiFn()// 请求数据完毕停止监听stop()}},// 刚进入视口区域就立刻执行回调{threshold: 0 })return {target}}
二、图片懒加载
1.使用场景
在页面中如果存在大量图片请求 同时请求可能造成网络堵塞
2.基础思路
监听图片元素是否已经进入到视口区域 如果进入就正式发起图片请求 (src="url")
3.技术实现
1. 使用useIntersectionObserver 监听图片是否进入视口区域2. 默认情况下部给src设置值 只有满足条件进入到视口区域才赋值3. 图片渲染一次之后停止监听
具体落地: 全局指令的形式
vue2.xVue.directive('指令',{inserted(el,binding){// el: 绑定了指令的dom元素// binding: value代表指令绑定表达式的值}})new Vue()
vue3.x
const app = createApp({})app.directive('指令名称',{mounted(el,binding){// el: 绑定了指令的dom元素// binding: value代表指令绑定表达式的值}})
基于vue-cli工程化环境下 定义全局指令
vue3.x中createApp方法没执行一次 都产生一个新的vue应用实例 他们不共享全局组件/全局指令
以插件化的机制进行全局指令的注册
const directivePlugin = {install(app){app.directive('指令名称',{// 图片懒加载逻辑mounted(el,binding){// el:imgdom对象// binding: value 表达式值// 使用监听函数 在满足条件的情况下 把binding.value 交给 el的src属性}})}}createApp(APP).use(directivePlugin)
三、避坑
1.注释节点引起的拿到$el是text文本节点 不满足监听函数对于target的要求
export function unrefElement(elRef: MaybeElementRef) {const plain = unref(elRef)return (plain as VueInstance)?.$el ?? plain}// 如果传入的参数类型为vue实例对象 则使用实例对象身上的$el属性 如果不是那就是一般的dom对象 直接使用就可以// 而当组件模板中不只有一个根节点的时候, vue实例对象的$el属性拿到的是文本节点,不满足要求 over
2.在组件使用上防止递归调用 (在组件的模板区域 使用name属性作为组件的名称渲染)