前言
这篇文章会讲到:
1.Vue的生命周期到底是什么
2.Vue生命周期的执行顺序
3.生命周期的每个阶段适合做什么
4.我们的请求放在哪个生命周期会更合适
1.Vue的生命周期到底是什么
与其说是Vue的生命周期,我觉得不如说是其内组件的生命周期。 简单来说,它的生命周期就是用来描述一个组件从引入到退出的全过程。 那复杂来说呢?就是一个组件从创建开始经历了数据初始化,挂载,更新等步骤后,最后被销毁。
2.Vue生命周期的执行顺序
他整体是分为三个大阶段的,在三个大阶段中,有细分为若干的小阶段。我们可以在不同的阶段去做不同的事情,后文也会讲到不同的阶段适合我们去做具体什么事情的。
想要更详细了解Vue生命周期执行的流程可以去官网查看官方文档,这里借鉴禹神的讲义课件
父子组件的生命周期
在父组件挂载前阶段,子组件已经挂载完成了。
不光是挂载阶段,其他两个阶段我们也可以打印出来,但是在这里我就不细说了,直接上结论:
- 挂载阶段:父组件 beforeMount -> 子组件 created -> 子组件 mounted -> 父组件 mounted
- 更新阶段:父组件 beforeUpdate -> 子组件 beforeUpdate -> 子组件 updated -> 父组件 updated
- 销毁阶段:父组件 beforeDestroy -> 子组件 beforeDestroy -> 子组件 destroyed -> 父组件 destroyed
3.生命周期的每个阶段适合做什么
created: 在Vue实例创建完毕状态,我们可以去访问data、computed、watch、methods上的方法和数据,但现在还没有将虚拟Dom挂载到真实Dom上,所以我们在此时访问不到我们的Dom元素(el属性,ref属性此时都为空)。
我们在此时可以进行一些简单的Ajax,并可以对页面进行初始化之类的操作
beforeMount: 它是在挂载之前被调用的,会在此时去找到虚拟Dom,并将其编译成Render
mounted: 虚拟Dom已经被挂载到真实Dom上,此时我们可以获取Dom节点,$ref
在此时也是可以访问的。
我们在此时可以去获取节点信息,做Ajax请求,对节点做一些操作
beforeupdate: 响应式数据更新的时候会被调用,beforeupdate
的阶段虚拟Dom还没更新,所以在此时依旧可以访问现有的Dom。
我们可以在此时访问现有的Dom,手动移除一些添加的监听事件
updated: 此时补丁已经打完了,Dom已经更新完毕,可以执行一些依赖新Dom的操作。
但还是不建议在此时进行数据操作,避免进入死循环(这个坑我曾经踩过)
beforeDestroy: 在Vue实例销毁之前被调用,在此时我们的实例还未被销毁。
在此时可以做一些操作,比如销毁定时器,解绑全局事件,销毁插件对象等
4.我们的请求放在哪个生命周期会更合适
那么至此我们已经对于Vue的生命周期有了一个基本的了解,现在我们来说一说,我们的请求应该放到哪个生命周期中才最为合适。
一般来说,会有两种回答:created
和mounted
。 上文已经讲了,这两个回答,前者是数据已经准备好了,后者是连dom也已经加载完成了,那么到底哪个才是正确答案呢?
其实,两个都是可以的,但是mounted
会更好。
可能有人会说:
created
的时间会更早,早些调用不是会省很多时间吗?这样性能会不会更高一点别急,我们一点一点来看
- 首先,它确实是早了,但是早不了几微秒,所以这其实没有提高性能
- 其次,我们在
created
阶段并没有去做渲染,所以在接下来我们会去做Dom渲染,但是如果此时我们还做了Ajax操作,在Ajax结束之后就会返回数据,我们就会将其插入到主线程中去运行,去处理数据,但是我们要知道,在浏览器机制中,渲染线程跟js线程是互斥的,所以有可能我们做渲染的同时,另一边可能要处理Ajax返回的数据了,这时候渲染就有可能被打断,在处理完数组后,去进行重新渲染。 那如果在created
中有多个Ajax呢?我们又要重新进行渲染,所以在created
去做Ajax请求这明显不太合适。 - 还有,有的时候我们接到返回的数据的时候可能要在回调函数中去进行一些Dom的操作,可是
created
阶段我们还没有将真实Dom加载出来,所以相对而言我们还是在mounted
去调用要好一些
如果是服务端渲染,我们将其放入
created
中进行,因为服务端不支持mounted
。