Vue的生命周期与new Vue的源码对应关系

146 阅读1分钟

背景

最近在学习vu2的源码,上一篇总结了vue响应式的核心原理。本篇主要是把vue的声明周期和和源码中的位置做对应,方便后续学习。

vue的生命周期

image.png

1. new Vue

function Vue (options) {
  this._init(options)
}
// new Vue();相当于执行了实例上的_init方法
  1. this._init方法在那里设置的?
// initMixin(Vue)中设置。文件位置:src\core\instance\init.js
export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
      ...省略代码
  }
}
  1. _init方法做了哪些初始化操作(给实例上设置方法或者属性)
    initLifecycle(vm) // 给实例上添加声明周期相关的属性
    initEvents(vm) // 自定义组件事件监听
    initRender(vm) // 插槽处理
    callHook(vm, 'beforeCreate')
    // ---------------------beforeCreated----------------------
    initInjections(vm) // vm.$options.inject
    initState(vm) // data/props/methods/computed/watch
    initProvide(vm) // vm.$options.provide
    callHook(vm, 'created')
    // ----------------------created------------------------------

2. initEvents&lifecycle---initLifecycle

// 文件位置:src\core\instance\lifecycle.js
vm.$parent = parent
vm.$root = parent ? parent.$root : vm
vm.$children = []
vm.$refs = {}
vm._watcher = null
vm._inactive = null
vm._directInactive = false
vm._isMounted = false
vm._isDestroyed = false
vm._isBeingDestroyed = false

2. initEvents&lifecycle---initEvents自定组件事件

3. initInjections&reactive

// 初始化参数和代理设置
initInjections(vm) // vm.$options.inject
initState(vm) // data/props/methods/computed/watch
initProvide(vm) // vm.$options.provide

4. mounted阶段

// this._init方法最后会调用$mount方法,执行自动挂载
if (vm.$options.el) {
  vm.$mount(vm.$options.el)
}
  1. vm.$mont方法在哪里定义
// src\platforms\web\entry-runtime-with-compiler.js
const mount = Vue.prototype.$mount // 重写mount方法为不同的平台做适配
Vue.prototype.$mount = function (
     el ?  : string | Element,
     hydrating ?  : boolean): Component {
    
    el = el && query(el)
    const options = this.$options
    if (el) {
         template = getOuterHTML(el)
    }
    if (template) {
        const {
             render,
             staticRenderFns
        } = compileToFunctions(template, {
             outputSourceRange: process.env.NODE_ENV !== 'production',
             shouldDecodeNewlines,
             shouldDecodeNewlinesForHref,
             delimiters: options.delimiters,
             comments: options.comments
        }, this)
        options.render = render
        options.staticRenderFns = staticRenderFns
    }
    return mount.call(this, el, hydrating)
}
// 被重写的$mount方法
// src\platforms\web\runtime\index.js
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
  1. 最后执行的mountComponent做了哪些操作
function mountComponent(){
    callHook(vm, 'beforeMount')
    updateComponent = () => {
      // 首先执行render =》 vdom
      vm._update(vm._render(), hydrating)
    }
    new Watcher(vm, updateComponent, noop, {
        before () {
          if (vm._isMounted && !vm._isDestroyed) {
            callHook(vm, 'beforeUpdate')
          }
        }
      }, true)
}
  1. new Watcher把当前的vm的undataComponent方法---更新的方法加入到vm的依赖数组,完成了依赖的收集。