vue源码解读2:this._init()干了什么

174 阅读1分钟

来到vue>src>core>instance>init.ts文件

import { initProxy } from './proxy'
import { initState } from './state'
import { initRender } from './render'
import { initEvents } from './events'
import { mark, measure } from '../util/perf'
import { initLifecycle, callHook } from './lifecycle'
import { initProvide, initInjections } from './inject'
import { extend, mergeOptions, formatComponentName } from '../util/index'
import type { Component } from 'types/component'
import type { InternalComponentOptions } from 'types/options'
import { EffectScope } from 'v3/reactivity/effectScope'

let uid = 0
export function initMixin(Vue: typeof Component) {
    Vue.prototype._init = function (options?: Record<string, any>) {
        const vm: Component = this //定义vm为this
         vm._uid = uid++ //记录_init()的执行次数
         vm._isVue = true //将其标记为Vue实例而不必执行instanceof的标志(暂时不懂)
         vm.__v_skip = true//避免观察实例(暂时不懂)
         vm._scope = new EffectScope(true /* detached */)//影响范围(暂时不懂)
         vm._scope._vm = true//(暂时不懂)
         if (options && options._isComponent) {//优化内部组件实例化//由于动态选项合并非常缓慢//内部组件选项需要特殊处理(暂时不懂)
          initInternalComponent(vm, options as any)
         } else {
          vm.$options = mergeOptions(
            resolveConstructorOptions(vm.constructor as any),
            options || {},
            vm
          )
        }
        //暂时不懂
        if (__DEV__) {
          initProxy(vm)
        } else {
          vm._renderProxy = vm
        }
         //暂时不懂
        vm._self = vm
        initLifecycle(vm)**请看vue源码解析3:initLifecycle解析**
        initEvents(vm)
        initRender(vm)
        callHook(vm, 'beforeCreate', undefined, false /* setContext */)
        initInjections(vm) // resolve injections before data/props
        initState(vm)
        initProvide(vm) // resolve provide after data/props
        callHook(vm, 'created')

        if (__DEV__ && config.performance && mark) {
          vm._name = formatComponentName(vm, false)
          mark(endTag)
          measure(`vue ${vm._name} init`, startTag, endTag)
        }

        if (vm.$options.el) {
          vm.$mount(vm.$options.el)
        }
    }
}

//处理vue的options,
export function resolveConstructorOptions(Ctor: typeof Component) {
  let options = Ctor.options //Ctor为vue构造函数,定义options变量
  if (Ctor.super) {
    const superOptions = resolveConstructorOptions(Ctor.super) //定义父类options变量
    const cachedSuperOptions = Ctor.superOptions //定义父类以前的options变量
    if (superOptions !== cachedSuperOptions) { //如果父类options变量改变
      Ctor.superOptions = superOptions //那么更新vue的superOptions
      const modifiedOptions = resolveModifiedOptions(Ctor)//ctor.options的深拷贝对象检查,Ctor.options 上是否有任何后期修改/附加的选项
      // update base extend options
      if (modifiedOptions) {
        extend(Ctor.extendOptions, modifiedOptions)
      }
      options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
      if (options.name) {
        options.components[options.name] = Ctor
      }
    }
  }
  return options
}

 //如果latest[key] !== sealed[key]深拷贝latest对象
function resolveModifiedOptions(
  Ctor: typeof Component
): Record<string, any> | null {
  let modified
  const latest = Ctor.options
  const sealed = Ctor.sealedOptions
  for (const key in latest) {
    if (latest[key] !== sealed[key]) {
      if (!modified) modified = {}
      modified[key] = latest[key]
    }
  }
  return modified
}

为了下一章的铺垫,这一章要搞清楚vm.$options是什么,那么我们来到util>options.ts

export function mergeOptions(
  parent: Record<string, any>,
  child: Record<string, any>,
  vm?: Component | null
): ComponentOptions {
  if (__DEV__) {
    checkComponents(child)
  }

  if (isFunction(child)) {
    // @ts-expect-error
    child = child.options
  }

  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)

  // Apply extends and mixins on the child options,
  // but only if it is a raw options object that isn't
  // the result of another mergeOptions call.
  // Only merged options has the _base property.
  if (!child._base) {
    if (child.extends) {
      parent = mergeOptions(parent, child.extends, vm)
    }
    if (child.mixins) {
      for (let i = 0, l = child.mixins.length; i < l; i++) {
        parent = mergeOptions(parent, child.mixins[i], vm)
      }
    }
  }

  const options: ComponentOptions = {} as any
  let key
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField(key: any) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}

mergeOptions( resolveConstructorOptions(vm.constructor as any), options || {}, vm )传了三个参数,第一个为

下一章解读initLifecycle(vm) (vm为_init的this)