文章目录
前言
此篇文章缘起于在业务开发中需要使用父子组件嵌套,子组件的数据源来自于父级的一个接口请求,
虽然这个我们的后端同学接口有redis缓存,但是身为一个前端码农,本着挖掘的思想,开始了父子组件能之间如何优化,
避免由于数据延迟导致子组件数据为空的情况(虽然v-if判断DOM结构能实现,但是页面上会有0.5s左右的结构变化,显然不是解决问题的最终办法)
一、为什么会出现这种情况?
让我们先来看一下vue中 父子组件各种生命周期的执行顺序:
1.渲染顺序
父beforeCreate=>父created=>父beforeMount=>父beforeCreate=>子created=>子beforeMount=>子mounted=>父mounted
2.子组件更新过程
父beforeUpdate=>子beforeUpdate=>子update=>父updated
3.父组件更新过程
父beforeUpdate=>父updated
4.销毁过程
父beforeDestroy=>子beforeDestroy=>子destroyed=>父destoryed
可以看出渲染时是父组件在创建之前稍微等待了一下,然后去渲染子组件,而我们如果在父组件mounted或者created里面去请求一个接口同时传值到子组件上,若接口返回数据时间过长,很容易出现子组件数据还没到就已经渲染完成的情况。总结出来部分解决办法,同时温故知新了一下Vue的动态异步组件相关知识,如下:
二、常用解决办法
1.使用v-if来判断是否有数据来展示dom结构(一般般)
这个可以说是很经典的一个办法,但是会有展示上的问题,即dom结构会先消失而后重新渲染
并不算是一个完美的解决方案,所以暂时Pass掉
2.通过$set来触发Vue的数据重新渲染机制(鸡肋)
鸡肋,大多数情况下要配合监听来使用,那么问题来了,我为什么不直接使用监听呢?
3.通过监听子组件数据源来实现子组件数据动态改变(基本完美)
watch:{
filterList:{//父组件传过来的数据源
deep:true,
immediate:true,handler(newValue){if(newValue){this.$set(this,'filterListCopy', newValue);//触发vue的重新渲染机制}},},},
值得一说的是监听属性的immediate为是否在这个监听属性挂载成功之后先执行以下handler里面的方法,以及deep为深层嵌套的对象或数组的监听,都是必须要加的
这个时候我脑海又衍生了一个新的问题:能否在组件导入配置的时候进行优化?
答案是肯定可以的,先让我们来看看Vue对异步组件挂载相关的说明:
显而易见的两个作用:
1.大大节省了JS包的大小,可以视为一个项目优化点,能看见这个组件的时候才会进行加载肯定是极美的
2.组件里面的数据会被进行缓存,下次时候可以重新进行渲染,自带自动缓存系统
它甚至支持返回promise和工厂模式在main.js进行全局封装:
我们在实际开发中可以如何优化组件引入相关的逻辑呢?
很简单,看一下你的项目 如果目前组件是这种导入方式 import xxx from xxx
可以通过改为:
// 组件改为异步按需加载,不再走父子组件的生命周期,优化响应速度
Vue.component('??',()=>import('@/??/??.vue'));
来实现动态加载以及异步加载,这个时候相应的组件会跳出父子组件的生命周期
前后变化
如图所示
页面默认会把所有的js文件(除导入的库),打包成一个整体的js文件,进入指定页面后进行一次性编译
配置完动态组件之后:
显而易见 这些组件会被从app.js的文件里面抽离出来,在页面需要的时候跟app.js文件一起进行加载
类似于小程序分包的一个效果,是一个很不错的优化点,在业务越来越多,需求越来越多的PC端,我们需要高复用性,低耦合性组件的同时是否可以考虑使用动态组件来优化一下组件加载速度呢?
总结
好记性不如烂笔头
随时随地给自己对项目的状态进行实时的记录,想来以后回忆起来也是极美的
明天,又是充满希望的一天!
最后放上一张镇楼图
版权归原作者 毕竟我是崔战神阿 所有, 如有侵权,请联系我们删除。