Vue生命周期的学习笔记

Vue生命周期的学习笔记

1. 概念/定义

每一个 vue 实例从创建到销毁的过程,就是这个 vue 实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染->更新->渲染、卸载等一系列过程。

通俗来说,vue 生命周期是指vue中实例或组件从创建到消灭经过的一系列过程。

2. 语述

学习之前,我们先根据官网的生命周期图,从图上,我们再一步一步来理解vue生命周期。

在这里插入图片描述

首先,从图上,我们可以看出来,整个过程是

  1. new Vue() 实例化一个 vue实例,然后init初始化event 和 lifecycle,其实这个过程中分别调用了3个初始化函数(initLifecycle(),initEvents(),initRender()),分别初始化了生命周期,事件以及定义createElement函数,初始化生命周期时,定义了一些属性,比如表示当前状态生命周期状态的 _isMounted_isDestroyedisBeingDestroyed,表示 keep-alive中组件状态的 _inactive,而初始化 event时,实际上就是定义了 o n c e 、 once、 onceoff、 e m i t 、 emit、 emiton 几个函数。而 createElement 函数是在初始化 render时定义的(调用了initRender函数)
  2. 执行 beforeCreate 生命周期函数
  3. beforeCreate执行完后,会开始进行数据初始化,这个过程,会定义data数据,方法以及事件,并且完成数据劫持observe以及给组件实例配置watcher观察者实例。这样,后续当数据发生变化时,才能感知到数据的变化并完成页面的渲染
  4. 执行created生命周期函数,所以,当这个函数执行的时候,我们已经可以拿到data下的数据以及methods下的方法了,所以在这里,我们可以开始调用方法进行数据请求了
  5. created执行完后,我们可以看到,这里有个判断,判断当前是否有el参数,如果有,我们再看是否有template参数。如果没有el,那么我们会等待调用$mount(el)方法。
  6. 确保有了el后,继续往下走,判断当有template参数时,我们会选择去将template 模板转换成 render 函数(其实在这前面是还有一个判断的,判断当前是否有render函数,如果有的话,则会直接去渲染当前的render函数,如果没有那么我们才开始去查找是否有template模板),如果没有 template,那么我们就会直接将获取到的el(也就是我们常见的#app,#app里面可能还会有其他标签)编译成template,然后在将这个template 转换成 render函数。
  7. 之后再调用beforeMount,也就是说实际从created到beforeMount之间,最主要的工作就是将模板或者el 转换为render函数。并且我们可以看出一点,就是你不管是用el,还是用 template,或者是用我们最常用的.vue文件(如果是.vue文件,他其实是会先编译成为template),最终他都是会被转换为 render函数的。
  8. beforeMount调用后,我们是不是要开始渲染render函数了,首先我们会先生产一个虚拟dom(用于后续数据发生变化时,新老虚拟dom对比计算),进行保存,然后再开始将render渲染成为真实的dom。渲染成真实dom后,会将渲染出来的真实dom替换掉原来的vm.$el,然后再将替换后的 $el append 到我们的页面内。整个初步流程就算是走完了
  9. 之后再调用mounted,并将标识生命周期的一个属性_isMounted 置为 true。所以 mounted函数内,我们是可以操作dom的,因为这个时候dom已经渲染完成了。
  10. 再之后,只有当我们状态数据发生变化时,我们在触发beforeUpdate,要开始将我们变化后的数据渲染到页面上了(实际上这里是有个判断的,判断当前的 _isMounted 是不是为 ture并且_isDestroyed是不是为false,也就是说,保证dom已经被挂载的情况下,且当前组件并未被销毁,才会走update流程)
  11. beforeUpdate调用之后,我们又会重新生成一个新的虚拟dom(Vnode),然后会拿这个最新的Vnode和原来的Vnode去做一个diff运算,这里就涉及到一系列的计算,算出最小的更新范围,从而更新render函数中的最新数据,再将更新后的render函数渲染成真实dom。也就完成了我们的数据更新
  12. 然后再执行updated,所以updated里面也可以操作dom,并拿到最新更新后的dom。不过,mounted和updated的执行,并不会等待所有子组件都被挂载完成后再执行,所以如果你希望所有视图都更新完毕后再做些什么事情,那么你最好在mounted或者updated中加一个 n e x t T i c k ( ) ,然后把要做的事情放在 nextTick(),然后把要做的事情放在 nextTick(),然后把要做的事情放在netTick() 中去做。
  13. 再之后beforeDestroy,实例销毁前,也就是说在这个函数内,你还是可以操作实例的。
  14. 之后会做一系列的销毁动作,接触各种数据引用,溢出事件监听,删除组件 _watcher,删除子实例,删除自身self等。同时将实例属性_isDestroyed置为true
  15. 销毁完成后,再执行destroyed

3. created 和 mounted区别

created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted:在模板渲染成html后调用,通常初始化页面完成后,再对html的dom节点进行一些需要的操作。

通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进行操作,比如插件chart.js的使用。如果写入created中,你会发现无法对chart进行一些初始化配置,一定要等到 html 渲染完成才可以进行,这时候就需要用到mounted。

猜你喜欢

转载自blog.csdn.net/weixin_45866849/article/details/128455809