Vue源码分析--Vue.mixin

Vue源码分析–Vue.mixin

看源码,就是将mixin对象合并到this.options上

export function initMixin (Vue: GlobalAPI) {
  Vue.mixin = function (mixin: Object) {
  	// 注意:这里的this.options不是指vm.$options, 而是Vue.options
  	// 初始为 Vue.options = 
  	// {filters: {}, directives: {}, components: {KeepAlive}, _base: Vue}
    this.options = mergeOptions(this.options, mixin)
    return this
  }
}

具体代码如下,这里删去了不重要的代码

export function mergeOptions (
  parent: Object,  // 父组件的options对象,这里指代 Vue.options
  child: Object,  // 将要合并的options对象,这里指代 mixin
  vm?: Component
): Object {
  // 检查child.components中的组件名key是否合法
  checkComponents(child)
  
  // 将props属性正规化,并特殊处理Array和Object类型
  // options.props = ['str', 'my-foo'] 
  // 	=> options.props = {str: {type: null}, myFoo: {type: null}}
  // options.props = {str1: String, str2: {type: String, required: true}} 
  // 	=> {str1: {type: String}, str2: {type: String, required: true}}
  normalizeProps(child, vm)
  
  // 将inject属性正规化
  // options,inject = ['key1', 'key2']
  // 	=> {key1: {from: 'key1'}, key2: {from: 'key2'}}
  // options.inject = {key1: 'obj1', key2: obj2}
  // 	=> {key1: {from: 'obj1'}, key2: {from: 'key2', ...obj2}}
  normalizeInject(child, vm)
  
  // 将directives属性正规化
  // options.directives = {my-dir: fn}
  // 	=> {my-dir: {bind: fn, update: fn}}
  normalizeDirectives(child)

  // 在生成构造函数Vue时,有这么一句 Vue.options._base = Vue
  // 即child 不是Vue 或者Vue的子组件的options时,处理里面的内容
  if (!child._base) {
  	// child.extends 对象可以看做是一个 mixin 对象
    if (child.extends) {
      parent = mergeOptions(parent, child.extends, vm)
    }
    // child.mixins = [options1, options2]
    // mixins表示多个mixin,否则child表示mixin本身
    if (child.mixins) {
      for (let i = 0, l = child.mixins.length; i < l; i++) {
        parent = mergeOptions(parent, child.mixins[i], vm)
      }
    }
  }

  const options = {}
  let key
  
  // 这里的parent === Vue.options ,并且合并了child.mixins与child.extend属性
  // 初始值为 {filters: {}, directives: {}, components: {KeepAlive}, _base: Vue}
  // 遍历parent中的属性,将parent[key]与child[key]一起合并到options中
  for (key in parent) {
    // 合并方式在下面
    mergeField(key)
  }
  // 此时parent属性已合并完成,
  // 并且(key in child) && (key in parent)的属性已处理完成
  // 剩下的,将只在child中存在,parent中不存在的属性复制到options中
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  
  // Function: 将parent[key]与child[key]一起合并到新对象options[key]上,分两种情况
  // 1. 若key为内置属性(如:['data', 'props', 'methods', 'inject', 'computed', 'watch', 
  // 'provide', 'components', 'filters', 'directives', '生命周期'...]),进行特殊方式合并
  // 2. 若key为非内置属性,用非空child[key]取代parent[key]
  function mergeField (key) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值