生命周期函数就是组件在初始化或者数据更新时会触发的钩子函数。
创建前/后
在初始化时,会调用以下代码,生命周期就是通过 callHook 调用的
Vue.prototype._init = function(options) {
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate') // 拿不到 props data
initInjections(vm)
initState(vm)
initProvide(vm)
callHook(vm, 'created')
}
- 在
beforeCreate
钩子函数调用的时候,是获取不到props
或者data
中的数据的,因为这些数据的初始化都在initState
中。 - 然后会执行
created
钩子函数,在这一步的时候已经可以访问到之前不能访问到的数据,但是这时候组件还没被挂载,所以是看不到的。 实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。
然后:
挂载前/后
接下来会执行挂载函数 :
export function mountComponent {
callHook(vm, 'beforeMount')
// ...
if (vm.$vnode == null) {
vm._isMounted = true
callHook(vm, 'mounted')
}
}
- beforMounted:挂载开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。
- mounted:挂载完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。 将
VDOM
渲染为真实DOM
并且渲染数据。组件中如果有子组件的话,会递归挂载子组件,只有当所有子组件全部挂载完毕,才会执行根组件的挂载钩子。
更新前/后
接下来是数据更新时会调用的钩子函数
beforeUpdate:在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程
updated(更新后):在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用
销毁前/后
最后就是销毁组件的钩子函数了
在执行销毁操作前会调用 beforeDestroy 钩子函数,然后进行一系列的销毁操作, 如果有子组件的话,也会递归销毁子组件,所有子组件都销毁完毕后才会执行根组件的 destroyed 钩子函数。
参考:
vue源码解析: https://nlrx-wjc.github.io/Learn-Vue-Source-Code/
博客文章:https://www.jianshu.com/p/672e967e201c