MergeOptions is one of the most important functions in Vue. It is used to combine the parent options and child Options properties to create a new option based on some merging strategy. Options here are the objects used to generate the VM instance. The root VM and the non-root VM are created differently in Vue: the root VM is generated directly by options, whereas the non-root VM is generated by options first and then by constructor. So mergeOptions is involved in both instantiation and constructor inheritance, the difference is whether or not the third parameter VM is passed.

function mergeOptions(parent, child, vm) {
  if(typof child === 'functions') {
    child = child.options
  }
  
  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)
  
  if(! child._base) {// If extend, mixin attributes exist, merge them into parent
    if(child.extends) {
      parent = mergeOptions(parent, child.extends, vm)
    }
    
    if(child.mixins) {
      for(let i = 0, l = child.mixin.length; i < l; ++i) {
        parent = mergeOptions(parent, child.mixin[i], vm)
      }
    }
  }
  
  let options = {}
  let key
  
  for(key in parent) {
    mergeField(key)
  }
  
  for(key in child) {
    // The key in both child and parent is already handled above
    if(! hasOwn(parent, key)) { mergeField(key) } }function mergeField(key) {
    const strat = strats[key] || defaultStrat
    
    options[key] = strat(parent[key], child[key], vm, key)
  }
  
  return options
}
Copy the code

What mergeOptions does:

  • Support different ways to write childprops,inject,directivesAttributes are converted to a unified form
  • Apply childmixinextend
  • Put the values of all attributes in accordance withstratsThe corresponding merge strategy is merged into a value, and a new options is generated to return it

All strats contain merge strategies for different attributes, which fall into the following categories:

  • hooks:parentValuechildValueInto an array,childValueValues in the following order
  • assets(filter,components,directives) : The combined value is{... Object.create(parentValue), ... childValue }
  • computed,props,methods,injects: The combined value is{... parentValue, ... childValue }
  • watch: After the merge into an object, the merge strategy for each attribute of the object andhooksSimilarly, the corresponding values are an array
  • dataprovides: If passed tomergeOptionsThe third parameter, VM, is not empty, indicating the instantiation of the root VM; otherwise, it indicates the generation of the component constructor. But the final value after the merge is a function, the function of the internalparentValueAnd then generatechildValueAnd then throughmergeDataIn turnparentValueThere are butchildValueAttributes that do not exist in thechildValueThe reactive property of. For properties that have both, and whose values are objects but not equal, the values of both properties are recursively calledmergeData
  • Other:defaultStratIn order tochildValueGive priority to

It seems that, with the exception of the data and provides merge strategies, the third parameter, VM, is used only for more detailed error reporting.

Global search for mergeOptions(it is called in the following places:

  • The root of vm_initGenerated in thevm.$options
  • resolveConstructorOptionsTo update the parent constructoroptions
  • Vue.extendGenerated in theSub.options
  • Vue.mixinGenerated in thethis.options
  • mergeOptionsInternal recursive processingmixinsextendWhen the attribute

The first of these is merge during instance generation, the second, third, and fourth can all be merge during update or constructor generation, and the fifth depends on whether the outer calls belong to the first or the other three.