# 【源码】生命周期 源码解析

# 前言

生命周期的源码比较简单,这里就不从入口开始一步一步讲了

# 源码解析

我们知道Vue的mixin机制会把生命周期的回调函数存在一个数组中




 
vm.$options={
    mounted:[fn,fn,fn...]
}

然后Vue源码是通过callHook函数来调用这些回调,达到生命周期执行的效果, 如




 








 Vue.prototype._init = function (options) {
      vm._self = vm;
      initLifecycle(vm);
      initEvents(vm);
      initRender(vm);
      callHook(vm, 'beforeCreate');
      initInjections(vm); // resolve injections before data/props
      initState(vm);
      initProvide(vm); // resolve provide after data/props
      callHook(vm, 'created');
 }

因为initState的执行在beforeCreatecreated 之间,所以在beforeCreate生命周期里面是拿不到data数据的

我们来看一下callHook函数




 











export function callHook (vm: Component, hook: string) {
  pushTarget()
  const handlers = vm.$options[hook]
  const info = `${hook} hook`
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      invokeWithErrorHandling(handlers[i], vm, null, vm, info)
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
  popTarget()
}

从代码上我们可以发现两个点

  • 内部很简单,是通过遍历数组的形式让生命周期的回调函数执行

  • 向外暴露事件hook, 这也是为什么我们可以通过@hook来获取到某个组件的生命周期的原因

我们对生命周期的原理有了大致了解之后,我们再来看下各个生命周期都在什么时候执行




 
































// Vue初始化的时候
Vue.prototype._init(opt){
    ... 合并选项
    ... 设置初始值 ,事件 等数据
    initLifecycle(vm)
    callHook(vm, 'beforeCreate');
    ... 初始化选项等数据
    callHook(vm, 'created');
    ...获取挂载的DOM 父节点
    callHook(vm, 'beforeMount');
    ...解析模板成渲染函数,并执行渲染函数,生成DOM插入页面
    vm._isMounted = true;
    callHook(vm, 'mounted');
}

// 组件更新的时候
Vue.prototype._update = function(
    vnode, hydrating
) {    
    if (vm._isMounted) {
        callHook(vm, 'beforeUpdate');
    }
    ...重新调用渲染函数,对比旧节点和新节点,得到最小差异,然后只更新这部分页面
    callHook(vm, 'updated');
}

// 节点被移除时会调用这个函数
Vue.prototype.$destroy = function() {
    callHook(vm, 'beforeDestroy');
    vm._isBeingDestroyed = true;
    ...实例被消除,移除所有 watcher
    vm._isDestroyed = true;
    ...DOM被移除
    callHook(vm, 'destroyed');
}

# 总结

生命周期的源码超级简单,就是遍历mixin机制合并之后的生命周期回调函数数组,然后依次执行,但是我们也发现了另外一点就是我们可以通过@hook获取到组件的生命周期