父子组件的生命周期执行流程是怎么样的呢?
在vue中有一道面试必问题,那就是vue的生命周期。
月薪5K的回答:
beforeCreate=>created=>beforeMount=>mounted=> beforeUpdate=>updated=>beforeDestroy=>destroyed
有点经验的能勉强扯扯keep-alive的两个生命周期:
activated和deactivated
正文:
我们都知道vue是组件化开发思想,下面来抛出我们日常开发中最常见的一个业务场景,比如一个编辑功能如下图:有两个组件,父组件嵌套子组件,在子组件里面有一个下拉选择框,我们在父组件里面调后端接口获取数据,传给子组件,渲染到页面。你是怎么做的呢?
一、错误写法:
在父组件的Created,获取数据赋值给data对象,然后通过prop的方式传给子组件,子组件在Created里面接收处理数据,渲染到页面。
对于组件通信,要补课的同学可以看看我这篇文章。
下面我们来演示这种错误写法:
父组件:
子组件:
子组件数据:
在子组件的ceated里面处理父组件传过来的数据:
页面效果:
页面显示了枚举值5对应的城市:厦门。
很多人是不是在想:咦~东东吖,你不是说这是错误写法吗?这不就是我们想要的效果吗?我平时也是这样写的,没有问题呀!!!
别急,我们是不是漏了什么呢???我刚刚说的是从后端获取数据,从后端获取数据我们的数据会受到网络等因素的影响,那代表什么?那代表会有异步产生。
我们用settimeout来模拟异步请求。
这个时候我们会发现,我们的页面是没有选中的,平时大家这样写,是会有bug的,因为我们的数据会受到网络等因素制约,当后端返回的数据比较快时,我们可能在页面正常展示了数据,但当后端返回的数据较慢时,我们的页面就不能正常地展示数据,就会出现bug,而且这种bug不是必现的,有的同学就会觉得很诡异。对了,这里除了网络因素,组件被v-show控制时,组件没有被销毁,只会在第一次走created这个生命周期,比如你点击多条数据的编辑按钮,还可能出现上一条的数据。我们需要编辑的时候把上一次的值置空,再获取对应的值赋值
那怎么解决呢?我们都是知道初次渲染,单组件的生命周期是:
beforeCreate=>created=>beforeMount=>mounted
那父子组件他们的生命周期又是怎么样的呢?
少废话,控制台:
我们发现父子组件的生命周期执行流程:父组件执行了前三个生命周期:beforeCreate=>created=>beforeMounted,然后等子组件执行完四个生命周期:beforeCreate=>created=>beforeMount=>mounted,父组件再执行了mountedued
父组件先执行了Created这个生命周期,然后等子组件执行了Created,最后再挂载的,按道理我们在父组件的Created里面通过props传值,在子组件的Created里面处理数据是没问题的,但是你有没有想过,我们的生命周期不会等我们的异步请求呀,尤雨溪对vue做性能设计的时候可没那么傻。
对了,尤雨溪懂个锤子vue(滑稽)!来人,给我把尤雨溪摁住!!!前两天听他直播讲vue3的生态,最近一两个月他就要强制更新vue的官网到vue3了。
回归正题:
我们在父组件的Created里面模拟一个异步请求:
在父子组件里面的created里面打印这个枚举值值,打开控制台查看结果:
我们发现无论父组件还是子组件,我们都不能获取到我们的枚举值6
要想在子组件获取到这个枚举值6,渲染到页面上,我们应该怎么做呢?
二、野鸡写法:
这时候,有的同学就会想到,我们只要在子组件里面获取到这个值,就能解决这个bug,那我们能不能利用v-if重新构建vue实例呢?从而打断我们的父子组件原本的生命周期执行流程。当value存在的时候再渲染这个子组件
我们打开控制台查看结果,发现父子组件的生命周期执行流程被v-if阻断了,变成了两个单组件的生命周期,先执行了父组件,当value这个值存在的时候,再创建vue实例,执行子组件的生命周期,并在子组件成功获取到了这个枚举值6
页面效果:
这个时候页面确实展示了我们想要的效果,但是这个子组件是获取到值了,才渲染的,也就是说,他获取到值了,整个子组件1秒后才闪现展示到我们的页面的(自行想象),我不能说你这种写法错误,只能这种写法真的野鸡。
野鸡???
啥是野鸡? 懂的都懂,不懂的请输入以下词条自行类比:
三、家鸡写法:
用watch监听属性值,监听到值后,再处理数据。
打开控制台,我们是发现我们是能在watch里面监听到这个枚举值6的。
页面效果:"美丽,这个问题解决了"。
最后补充一点:我们这里是监听的一个属性,当我们监听的是一个对象,还需要利用deep深度监听,并通过immediate立即渲染。这里我就不再演示了,同学们自己试一试哦(其实是因为我懒,不想写示例了,哈哈哈)
总结:
对于一些配置数据,比如我们需要传入一个属性,来控制disabled,这种可以直接在组件上赋值,类似于第一种Created里面直接赋值,不过在组件上直接赋值代码更加简洁。但对于异步数据,我们必须用watch来监听赋值,如果监听的是对象,还需要设置深度监听和立即渲染两个属性。
最后:还有什么写法,欢迎在评论区留言哦!
- 东东吖带你打通全栈,go-vue-react项目介绍
- 【vue进阶之旅】如何自定义组件v-model,封装属于自己的组件库?
- 【vue进阶之旅】如何使用keep-alive做组件缓存?
- 发生跨域的时候,服务器到底有没有接收到请求?
- vue进阶之路:vue3.2-setup语法糖、组合式API、状态库Pinia归纳总结
- 跨域问题及前后端常见解决方案?
- 微信小程序如何分包?
- 前端性能优化,如何提高首屏加载速度?
- 项目中的配置文件都是干嘛的?
- 从0到1学习Node.js系列教程(第一篇):API接口初体验
- 父子组件的生命周期执行流程是怎么样的呢?
- 1024程序员这天,我发现了掘金官方的一个bug。
- 组件通信的8种方式,你搞清楚了吗?
- 手把手教你利用XSS攻击体验一次黑客