阅读 242

父子组件的生命周期执行流程是怎么样的呢?

在vue中有一道面试必问题,那就是vue的生命周期。

月薪5K的回答:

beforeCreate=>created=>beforeMount=>mounted=> beforeUpdate=>updated=>beforeDestroy=>destroyed

有点经验的能勉强扯扯keep-alive的两个生命周期:

activated和deactivated

正文:

我们都知道vue是组件化开发思想,下面来抛出我们日常开发中最常见的一个业务场景,比如一个编辑功能如下图:有两个组件,父组件嵌套子组件,在子组件里面有一个下拉选择框,我们在父组件里面调后端接口获取数据,传给子组件,渲染到页面。你是怎么做的呢?

image.png

一、错误写法:

在父组件的Created,获取数据赋值给data对象,然后通过prop的方式传给子组件,子组件在Created里面接收处理数据,渲染到页面。

对于组件通信,要补课的同学可以看看我这篇文章。

组件通信的8种方式,你搞清楚了吗?

下面我们来演示这种错误写法:

父组件:

image.png

子组件:

image.png

子组件数据:

image.png

在子组件的ceated里面处理父组件传过来的数据:

image.png

页面效果:

image.png

页面显示了枚举值5对应的城市:厦门。

很多人是不是在想:咦~东东吖,你不是说这是错误写法吗?这不就是我们想要的效果吗?我平时也是这样写的,没有问题呀!!!

别急,我们是不是漏了什么呢???我刚刚说的是从后端获取数据,从后端获取数据我们的数据会受到网络等因素的影响,那代表什么?那代表会有异步产生。

我们用settimeout来模拟异步请求。

image.png

这个时候我们会发现,我们的页面是没有选中的,平时大家这样写,是会有bug的,因为我们的数据会受到网络等因素制约,当后端返回的数据比较快时,我们可能在页面正常展示了数据,但当后端返回的数据较慢时,我们的页面就不能正常地展示数据,就会出现bug,而且这种bug不是必现的,有的同学就会觉得很诡异。对了,这里除了网络因素,组件被v-show控制时,组件没有被销毁,只会在第一次走created这个生命周期,比如你点击多条数据的编辑按钮,还可能出现上一条的数据。我们需要编辑的时候把上一次的值置空,再获取对应的值赋值

那怎么解决呢?我们都是知道初次渲染,单组件的生命周期是:

beforeCreate=>created=>beforeMount=>mounted

那父子组件他们的生命周期又是怎么样的呢?

少废话,控制台:

image.png

我们发现父子组件的生命周期执行流程:父组件执行了前三个生命周期:beforeCreate=>created=>beforeMounted,然后等子组件执行完四个生命周期:beforeCreate=>created=>beforeMount=>mounted,父组件再执行了mountedued

父组件先执行了Created这个生命周期,然后等子组件执行了Created,最后再挂载的,按道理我们在父组件的Created里面通过props传值,在子组件的Created里面处理数据是没问题的,但是你有没有想过,我们的生命周期不会等我们的异步请求呀,尤雨溪对vue做性能设计的时候可没那么傻。

对了,尤雨溪懂个锤子vue(滑稽)!来人,给我把尤雨溪摁住!!!前两天听他直播讲vue3的生态,最近一两个月他就要强制更新vue的官网到vue3了。

_-1916587870_IMG_20211023_114401_1634960644000_xg.jpg

回归正题:

我们在父组件的Created里面模拟一个异步请求:

image.png

在父子组件里面的created里面打印这个枚举值值,打开控制台查看结果:

image.png

我们发现无论父组件还是子组件,我们都不能获取到我们的枚举值6

要想在子组件获取到这个枚举值6,渲染到页面上,我们应该怎么做呢?

二、野鸡写法:

这时候,有的同学就会想到,我们只要在子组件里面获取到这个值,就能解决这个bug,那我们能不能利用v-if重新构建vue实例呢?从而打断我们的父子组件原本的生命周期执行流程。当value存在的时候再渲染这个子组件

image.png

我们打开控制台查看结果,发现父子组件的生命周期执行流程被v-if阻断了,变成了两个单组件的生命周期,先执行了父组件,当value这个值存在的时候,再创建vue实例,执行子组件的生命周期,并在子组件成功获取到了这个枚举值6

image.png

页面效果:

image.png

这个时候页面确实展示了我们想要的效果,但是这个子组件是获取到值了,才渲染的,也就是说,他获取到值了,整个子组件1秒后才闪现展示到我们的页面的(自行想象),我不能说你这种写法错误,只能这种写法真的野鸡。

野鸡???

啥是野鸡?  懂的都懂,不懂的请输入以下词条自行类比:

image.png

三、家鸡写法:

用watch监听属性值,监听到值后,再处理数据。

image.png

打开控制台,我们是发现我们是能在watch里面监听到这个枚举值6的。

image.png

页面效果:"美丽,这个问题解决了"。

image.png

最后补充一点:我们这里是监听的一个属性,当我们监听的是一个对象,还需要利用deep深度监听,并通过immediate立即渲染。这里我就不再演示了,同学们自己试一试哦(其实是因为我懒,不想写示例了,哈哈哈)

image.png

总结:

对于一些配置数据,比如我们需要传入一个属性,来控制disabled,这种可以直接在组件上赋值,类似于第一种Created里面直接赋值,不过在组件上直接赋值代码更加简洁。但对于异步数据,我们必须用watch来监听赋值,如果监听的是对象,还需要设置深度监听和立即渲染两个属性。


作者:东东吖
链接:https://juejin.cn/post/7024151086436974623


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐