Vue源码02-静态方法和mergeOptions

2020-05-22  本文已影响0人  熊少年

通过上节我们对Vue的流程有了一个大概的了解,这节我们将进一步分析

Vue的静态方法

Vue.use

在我们写Vue项目的时候,应该都会用到这个东西,它的作用只有一个就是给我项目注册插件

  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    } 

    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args) 
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
Vue.mixin

不推荐在应用代码中使用

 Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
  }
Vue.extend

使用基础 Vue 构造器,创建一个“子类”。

Vue.extend = function (extendOptions) {
    extendOptions = extendOptions || {}
    const Super = this
    const SuperId = Super.cid
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
    if (cachedCtors[SuperId]) {
      return cachedCtors[SuperId]
    }
    const Sub = function VueComponent (options) {
      this._init(options)
    }
    .....
   cachedCtors[SuperId] = Sub
    return Sub
  }
Vue.component(),Vue.directive(),Vue.filter()
  ASSET_TYPES.forEach(type => {
    Vue[type] = function (
      id, definition
    ) {
      if (!definition) {
        return this.options[type + 's'][id]
      } else {
        if (type === 'component' && isPlainObject(definition)) {
          definition.name = definition.name || id
          definition = this.options._base.extend(definition)
        }
        if (type === 'directive' && typeof definition === 'function') {
          definition = { bind: definition, update: definition }
        }
        this.options[type + 's'][id] = definition
        return definition
      }
    }
  })

这里可以去看看官网对这几个静态方法的案例讲解,你就会非常清楚了

Vue.prototype._init

mergeOptions
export function mergeOptions (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  ...
  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)
  
 ...
  const options = {}
  let key
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    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
}

strats是一个对象
activated: ƒ mergeHook( parentVal, childVal )
beforeCreate: ƒ mergeHook( parentVal, childVal )
beforeDestroy: ƒ mergeHook( parentVal, childVal )
beforeMount: ƒ mergeHook( parentVal, childVal )
beforeUpdate: ƒ mergeHook( parentVal, childVal )
components: ƒ mergeAssets( parentVal, childVal, vm, key )
computed: ƒ ( parentVal, childVal, vm, key )
created: ƒ mergeHook( parentVal, childVal )
data: ƒ ( parentVal, childVal, vm )
deactivated: ƒ mergeHook( parentVal, childVal )
destroyed: ƒ mergeHook( parentVal, childVal )
directives: ƒ mergeAssets( parentVal, childVal, vm, key )
el: ƒ (parent, child, vm, key)
errorCaptured: ƒ mergeHook( parentVal, childVal )
filters: ƒ mergeAssets( parentVal, childVal, vm, key )
inject: ƒ ( parentVal, childVal, vm, key )
methods: ƒ ( parentVal, childVal, vm, key )
mounted: ƒ mergeHook( parentVal, childVal )
props: ƒ ( parentVal, childVal, vm, key )
propsData: ƒ (parent, child, vm, key)
provide: ƒ mergeDataOrFn( parentVal, childVal, vm )
serverPrefetch: ƒ mergeHook( parentVal, childVal )
updated: ƒ mergeHook( parentVal, childVal )
watch: ƒ ( parentVal, childVal, vm, key )
data,provide合并
// 代码截取
  if (!childVal) {
      return parentVal
    }
    if (!parentVal) {
      return childVal
    }
  ...
  //mergeData
  if (!hasOwn(to, key)) {
      set(to, key, fromVal) // 响应式添加
    } else if (
      toVal !== fromVal &&
      isPlainObject(toVal) &&
      isPlainObject(fromVal)
    ) {
      mergeData(toVal, fromVal) // 递归赋值
    }
props,methods,inject,computed合并
 if (!parentVal) return childVal
  const ret = Object.create(null)
  extend(ret, parentVal)
  if (childVal) extend(ret, childVal)
  return ret
'beforeCreate', 'created', 'beforeMount', 'mounted','beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', 'activated', 'deactivated', 'errorCaptured', 'serverPrefetch'合并
 const res = childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : Array.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal
  return res
    ? dedupeHooks(res)
    : res
// dedupeHooks
function dedupeHooks (hooks) {
  const res = []
  for (let i = 0; i < hooks.length; i++) {
    if (res.indexOf(hooks[i]) === -1) {
      res.push(hooks[i])
    }
  }
  return res
}

'component', 'directive', 'filter'合并
  const res = Object.create(parentVal || null)
  if (childVal) {
    return extend(res, childVal)
  } else {
    return res
  }

小节:

上一篇 下一篇

猜你喜欢

热点阅读