这是我参与「第四届青训营 」笔记创作活动的第7天
一、生命周期是什么
引用官网的话就是:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。即我们可以认为生命周期救是一个过程,在这个过程中他经历了很多我们看不到的操作,从而完成了一个页面的搭建,并将他展示在我们面前。
二、生命周期图示
三、生命周期图分析
app = Vue.create(option): 即创建一个vue实例,此时进入组件的创建过程。Init Events & Lifecycle: 初始化组件的事件和生命周期函数;当执行完这一步之后,组件的生命周期函数就已经全部初始化好了,等待着依次去调用。
- 初始化组件的事件:定义了一些属性,比如表示当前状态生命周期状态得_isMounted ,_isDestroyed ,_isBeingDestroyed,表示keep-alive中组件状态的_inactive
- 初始化组件的事件:实际上就是定义了
$once、$off、$emit、$on几个函数。
- 初始化组件的事件:定义了一些属性,比如表示当前状态生命周期状态得_isMounted ,_isDestroyed ,_isBeingDestroyed,表示keep-alive中组件状态的_inactive
beforeCreate: 在组件实例初始化完成之后立即调用,这是第一个生命周期函数,此时,组件的data和methods以及页面DOM结构都还没有初始化;所以此阶段,什么都做不了。Init injections & reactivity: beforeCreate执行完后,会开始进行数据初始化,这个阶段中,正在初始化 data 和 methods 中的数据以及方法,并且完成数据劫持observe以及给组件实例配置watcher观察者实例。created: 这个组件创建阶段第二个生命周期函数,此时,组件的 data 和 methods 已经可以用了;但是页面 还没有渲染出来;这时可以开始调用方法进行数据请求,所以此时经常会发起 HTTP 请求获取数据。- 接下来就是
解析模板结构: 把data上的数据拿到,并且解析执行模板结构汇总的指令;当所有指令被解析完毕,那么模板页面就被渲染到内存中了;当模板编译完成,我们的模板页面,还没有挂载到页面上,只是存在于内存中,用户看不到页面。 beforeMount: 当模板在内存中编译完成,会立即执行实例创建阶段的第三个生命周期函数,这个函数就是 beforeMount,此时内存中的模板结构,还没有真正渲染到页面上;此时,页面上看不到真实的数据,用户看到的只是一个模板页面而已。- beforeMount调用后,我们是不是要开始
渲染render函数了,首先我们会先生产一个虚拟dom(用于后续数据发生变化时,新老虚拟dom对比计算),进行保存,然后再开始将render渲染成为真实的dom。 mounted: mounted 是组件创建阶段最后的一个生命周期函数;此时,页面已经真正的渲染好了,我们是可以操作dom的,用户可以看到真实的页面数据了;当这个生命周期函数执行完,组件就离开创建阶段,进入到运行中的阶段;如果要使用一些第三方 UI 插件,而且这个插件还需要被初始化,那么,必须在 mounted 中来初始化插件。beforeUpdate: 状态数据发生变化时,就会触发beforeUpdate,这时要开始将我们变化后的数据渲染到页面上,但是还未进行渲染,所以数据肯定是最新的;但是页面上呈现的数据还是旧的。- beforeUpdate调用之后,我们又会重新
生成一个新的虚拟dom(Vnode),然后会拿这个最新的Vnode和原来的Vnode去做一个diff计算,这里就涉及到一系列的计算,算出最小的更新范围,从而更新render函数中的最新数据,再将更新后的render函数渲染成真实dom。也就完成了我们的数据更新 updated: 页面完成更新,此时,data数据是最新的,同时,页面上呈现的数据也只最新的,所以updated里面也可以操作dom,并拿到更新后的dom。
注意:mouted和updated的执行,并不会等待所有子组件都被挂载完成后再执行,如果你希望所有视图都更新完毕后再做些什么事情,最好在mouted或者updated中加一个$nextTick(),或者使用定时器,然后把要做的事情放在$netTick()或者定时器中去做。
例:
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: 'not updated'
}
},
methods: {
updateMessage: function () {
this.message = 'updated'
console.log(this.$el.textContent) // => 'not updated'
this.$nextTick(function () {
console.log(this.$el.textContent) // => 'updated'
})
}
}
}
13. beforeUnmount: 当执行beforeUnmount的时候,组件即将被销毁,但是还没有真正开始销毁,此时组件还是正常可用的;data、methods 等数据或方法,依旧可以被正常访问。之后会做一系列的销毁动作,解除各种数据引用,移除事件监听,删除组件_watcher,删除子实例,删除自身self等。此时一般也用来清除定时器等等。
14. unmounted: 组件已完成了销毁,执行unmounted,此时组件已经无法使用,data和methods都不可使用。
四、生命周期函数功能总结
- beforeCreate:创建之前,生命周期第一个函数;此时组件的 data 和 methods 以及页面DOM 结构都还没有初始化。
created:创建完成,此时组件的 data 和 methods 已经可以使用,但页面还没有渲染出来,通常在此发起 HTTP 请求获取数据。(常用)- beforeMount:挂载之前,此时模板在内存中编译完成,但还没有真正渲染到页面上。
mounted:挂载完成,此时页面已经渲染好,用户可以看到真实的页面数据。(常用)- beforeUpdate:页面数据更新之前。
- updated:页面数据更新完成。
beforeUnmount:组件被销毁之前。(常用)- unmounted:组件销毁完成。