每个Vue实例在被创建时都要经过一系列的初始化过程----如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己代码的机会;生命周期又称生命周期回调函数、声明周期函数;
上一张官网的生命周期图示:
其中红字红框白底的内容为生命周期钩子,图中所示共有八个钩子(4对),分别是:
beforeCreate---created,beforeMount---mounted,beforeUpdate---updated,beforeDestroy---destoryed
生命周期函数中的this指向是vm或组件实例对象;
- new Vue()
指实例化一个vue实例;生命周期的一切操作都是在vue实例创建的基础上实现的,这是大前提;
- Init Events& Lifecycle
初始化生命周期与事件,注意此时数据监测和数据代理还未发生;
- beforeCreate
由于还没有数据代理和数据监测,因此尚不能通过vm访问data中的数据以及methods中的方法;
- Init injections & reactivity
初始化数据监测与数据代理;
- created
由于已经做完了数据监测和数据代理,因此,此时可通过vm访问到data中的数据、methods中配置的方法;
- Has 'el' option?
这是一个判断条件,意思是是否有el配置项,之前说过,el配置项是绑定模板与Vue的纽带;
- Has 'template' option?
这是一个判断条件,意思是是否有template配置项;模板中可以不写任何dom元素,在template配置项中加入dom元素也能实现页面;
以上两个判断条件执行完毕后,Vue开始解析模板,生成虚拟DOM,但是该虚拟DOM存在内存中,页面并未显示解析好的内容;这两个判断条件具体在下面讲述:
- beforeMount
此时页面所呈现的是未经Vue编译的DOM结构,注意:在此钩子中所有对DOM的操作,最终都不奏效(因为后一步直接呈现最终页面);
- Create vm.$el and replace 'el' with it
此处创建vm.$el放在内存中(这一步是为了后面数据发生变化,将真实DOM和虚拟DOM对比,提高DOM复用效率),并替换el,此步过后,将内存中的虚拟DOM转为真实DOM插入页面;
- mounted
经过此步,页面上呈现的是经过Vue编译的DOM,此时对DOM的操作均有效,但是尽可能避免。至此,初始化过程结束,一般在此过程中进行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作;
- beforeUpdate
当页面数据需要更新时,更新之前触发该钩子,此时,vm中的数据时新的,但是页面依然是旧数据,即页面尚未和数据保持同步;
- Virtual DOM re-render and patch
根据上面一部拿到的新数据,重新生成新的虚拟DOM,随后将新DOM与旧的虚拟DOM进行比较,最终完成页面更新,实现了从Model(模板)--->View(页面)的更新;
- updated
这步才是真正的页面和数据保持同步,此时数据是新的,页面也是新的;
- when vm.$destroy() is called
即vm.$destroy()被调用时;会完全销毁一个实例,并清理它与其它实例的连接,解绑它的全部指令与事件监听器(自定义事件),触发下面的beforeDestroy和destroyed钩子
- beforeDestroy
此时:vm中所有的data、methods、指令等,都处于可用状态,但是马上要执行销毁过程;一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作;
注意:虽然vm被销毁了,但是vm销毁之前的工作成果还在,所以页面仍然会存在之间显示的结构;但是已经不能触发页面更新了;
- Teardown watchers,child components and event listeners
此步移除监视器、子组件以及事件监听器
- destroy
到此结束
补充说明一下上面的条件判断:
如果有el配置项和template配置项,则将template进行编译,解析模板,生成虚拟DOM放入内存;
若没有el配置项,则要在执行vm.$mount(el)时,才触发判断‘是否有template配置项’,若有该配置项,则跟上步一样对template进行编译解析;若没有template配置项,则将el的整个外部html元素作为template配置项进行编译,从而也会生成虚拟DOM存储;
补充生命周期函数activated和deactivated
这两个是路由组件所独有的两个钩子,用于捕获路由组件的激活状态,因为跳进另一个路由组件的时候,前一个路由组件会被销毁,但是加了缓存的路由,则不会被触发销毁流程;使用这两个替代销毁时的生命周期函数;
activated:表示路由组件被激活时触发;
deactivated:表示路由组件失活时触发;