Vue.component & Vue.extend & Vue.mixin分析

Vue.component()

Vue.component 用来注册或获取一个全局的组件,为什么说它是全局呢?因为通过该方法注册的组件都会添加到Vue.options.components中. ( Vue.directive 和 Vue.filter 也是同理) 下文中用 components 代替. 实际上Vue.component() 也只是 Vue.extend 的一层封装


Vue['component'] = function(id,options) {
    if(!options) {
      return this.options['components'][id]
    }
    // type 由上文传入的,
    if(type == "component" && options === "[object Object]") {
      options = this.options._base.extend(options)
    }
    this.options['components'][id] = options
    return options
}

参照官方文档的使用方法来逐一分析:

  1. 只传入 id 时, 从 components 上获取对应 id 的组件
    if(!options) {
      return this.options['components'][id]
    }
  1. 传入一个已经处理过的组件时,将会直接添加到 components 中,如果有相同的则替换
Vue.component("comp",Vue.component(...))
  1. 传入的配置项为[object Object]类型 时,则调用 Vue.extend 创建一个组件添加到 components 中.为什么要这样判断呢?因为通过Vue.extend创建的组件的类型是[object Function](Vuecomponent构造函数)

Vue.extend()

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

Vuecomponent 函数.它最终会返回作为一个组件的构造函数,也就上面提到的一个“子类”。内部的 this._init 也就是与Vue初始化时一致的方法

var Super = this  //  this == Vue
var Sub = function Vuecomponent(extendOptions) {
  this._init(extendOptions)
}

然后设置子类的prototype继承了Vue原型

Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = sub 

这一步至关重要,将用户传入的配置与 Super.options合并, Super.options上有一些基础的全局组件和指令, 这里的 Super.options 也就是 Vue.options

  Sub.options = mergeOptions(
    Super.options, // Vue.construct.options
    extendOptions // 用户传入的配置
  )

初始的 Super.options

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

接着在Sub上添加一个 “super” 属性,通过它就可以知道该构造函数是不是继承而来的.

Sub["super"] = Super 

接下来把 props 和 computed 代理到 Sub.prototype 上, 没搞懂这么做啥意思,等后面有头绪了再来补充。

if(Sub.options.props) {
  initProps$1(Sub)
}
if(Sub.options.computed) {
  initComputed$1(Sub)
}

添加一份对Super.options的引用,在后面初始化的时候, 如果验证Super.options与Vue.options不一致,则重新更新 superOptions

  • extendOptions 用户传入的配置
  • superOptions Vue构造函数上的options
  • sealedOptions 合并之后的配置
Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({},Sub.options)

最后返回了 Vuecomponent构造函数,至此Vue.extend的工作就结束了

return Sub

完整代码:

Vue.extend = function(extendOptions) {
  extendOptions = extendOptions || {}
  var Super = this
  var SuperId = Super.cid
  var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
  if(cachedCtors[SuperOd]) {
    return cachedCtors[SuperId]
  }
  var name = extendOptions.name || Super.options.name
  if(name) {
    // 校验组件名是否合规
    validateComponentName(name)
  }
  var Sub = function Vuecomponent(options) {
    this._init(options)
  }
  Sub.prototype = Object.create(Super.prototype)
  Sub.prototype.constructor = Sub
  Sub.cid = cid++
  Sub.options = mergeOptions(
    Super.options,
    extendOptions
  )
  Sub['super'] = Super
  if(Sub.options.prop) {
    initProps$1(Sub)
  }
  if(Sub.options.computed) {
    initComputed$1(Sub)
  }
  Sub.extend = Super.extend
  Sub.mixin = Super.mixin
  Sub.use = Super.use
  ASSET_TYPE.foreach(function(type){
    Sub[type] = Super[type]
  })
  if(name) {
    Sub.options.components[name] = Sub
  }
  Sub.superOptions = Super.options
  Sub.extendOptions = extendOptions
  Sub.sealeOptions = extend({},Sub.options)
  cachedCtors[SuperId] = Sub
  return Sub
}

Vue.mixin

mixin代码很简单,它是mergeOptions的封装

// @params mixin 用户传入的配置
Vue.mixin = function(mixin) {
  this.options = mergeOptions(this.options,mixin)
  return this
}

你可能感兴趣的:(Vue,vue.js,javascript,前端)