Vue源码分析(3)-- mergeOptions上篇

上一篇以init方法为入口,介绍了Vue实例化的过程。写的过程中觉得mergeOptions是一个重点,需要拉出来单独写一篇。不看懂mergeOption这个方法,在new Vue的过程中,参数到底是怎么合并到实例中去的,至少我是还有疑问的。
也就是说,下面的两个选项 el 以及 data到底在初始化的过程中经历了什么,我想要搞清楚。

 new Vue({
    el: '#app',
    data: {
        msg:'hello'
    }
})
mergeOptions
vm.$options = mergeOptions(
  resolveConstructorOptions(vm.constructor),
  options || {},
  vm
)

Vue使用 mergeOptions 来处理我们调用Vue时传入的参数选项(options),然后将返回值赋值给 this.$options 。mergeOptions 传入了三个参数:
(1) resolveConstructorOptions(vm.constructor)
(2)options || {}
(3)vm

第一个参数resolveConstructorOptions
export function resolveConstructorOptions (Ctor: Class) {
  let options = Ctor.options
  if (Ctor.super) {
    const superOptions = resolveConstructorOptions(Ctor.super)
    const cachedSuperOptions = Ctor.superOptions
    if (superOptions !== cachedSuperOptions) {
      // super option changed,
      // need to resolve new options.
      Ctor.superOptions = superOptions
      // check if there are any late-modified/attached options (#4976)
      const modifiedOptions = resolveModifiedOptions(Ctor)
      // 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
}

mergeOptions传入的(vm.constructor)对应 (Ctor: Class) ,也就是说Ctor等于vm,let options = Ctor.options等于let options = Vue.options
还记得 Vue.options 吗?上一篇里,整理了 Vue.options 应该初始化为下面这个样子,是否有印象?

Vue.options = {
components: {
KeepAlive,
Transition,
TransitionGroup
},
directives: {
model,
show
},
filters: {},
_base: Vue
}

之后第一个if判断是否定义了 Vue.super ,如果为真,将父类的options赋值给superOptions变量,将第一个参数传进来的vm.options赋值给cachedSuperOptions变量,并做比较,如果不一致执行vm.superOptions = superOptions,然后执行resolveModifiedOptions。这里主要是检查是否vm.options是否发生变化。

function resolveModifiedOptions (Ctor: Class): ?Object {
  let modified // 定义modified变量
  const latest = Ctor.options // 自身的options
  const extended = Ctor.extendOptions // 构造"自身"时传入的options
  const sealed = Ctor.sealedOptions // 执行Vue.extend时封装的"自身"options,这个属性就是方便检查"自身"的options有没有变化
 // 遍历当前构造器上的options属性,如果在"自身"封装的options里没有,则证明是新添加的。执行if内的语句。调用dedupe方法,最终返回modified变量(即”自身新添加的options“)
  for (const key in latest) {
    if (latest[key] !== sealed[key]) {
      if (!modified) modified = {}
      modified[key] = dedupe(latest[key], extended[key], sealed[key])//方法主要就是防止生命周期构造函数重复
    }
  }
  return modified
}

如果产生了变化,就将 extend(Ctor.extendOptions, modifiedOptions),深拷贝,然后继续执行options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)。
由此看来,这个参数方法是一个一层层把构造函数的父类option合进来的过程,是一个合并了父类的Options。

第二个参数options

传给 mergeOptions 方法的第二个参数是我们调用Vue构造函数时的参数选项

第三个参数 vm

vm也就是 this 对象, 也就是Vue.options。
通过对参数的解释,我们分析一下开篇new Vue后,mergeOptions传入的是哪些参数。

vm.$options = mergeOptions(
// Vue.options
{
components: {
KeepAlive,
Transition,
TransitionGroup
},
directives: {
model,
show
},
filters: {},
_base: Vue
},
// 调用Vue构造函数时传入的参数选项 options
{
el: '#app',
data: {
msg:‘hello’
}
},
// this
vm
)

你可能感兴趣的:(Vue源码分析(3)-- mergeOptions上篇)