mergeOptions


将2个配置选项合并到一个新的对象中

function mergeOptions ( parent, child,vm) {

 // 校验组件名是否符合规范,不能与 标签名和svg 名称重名
  if (process.env.NODE_ENV !== 'production') {
    checkComponents(child)
  }

// 合并的 child 是一个子类构造函数时,就取出它的options
  if (typeof child === 'function') {
    child = child.options
  }

 // 格式化 props、inject、directive
  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)

  // 如果 child 有 extends 和 mixins 配置则合并它们
  // 合并过配置的child 上会有 _base属性,所以无需再次合并
  if (!child._base) {
    if (child.extends) {
      parent = mergeOptions(parent, child.extends, vm)
    }
    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
  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
}

normalizeProps

格式化 props 的格式

function normalizeProps (options, vm) {
  const props = options.props
  // 没有配置 props 时直接跳出
  if (!props) return
  // 设置一个新的对象来保存格式化后的props
  const res = {}
  let i, val, name
  
  /*
  *  如果提供的是 Array格式的 props,依次遍历把数据格式化成
  *  props: {
       key: {type: null}
  *  }
  */
  
  if (Array.isArray(props)) {
    i = props.length
    while (i--) {
      val = props[i]
      if (typeof val === 'string') {
        name = camelize(val)
        res[name] = { type: null }
      }
    }
  } else if (isPlainObject(props)) {
  /*
   *  如果提供的是Object 类型,处理结果与Array类似
   *  props: {key: {type: Type}}
  */ 
    for (const key in props) {
      val = props[key]
      name = camelize(key)
      res[name] = isPlainObject(val)
        ? val
        : { type: val }
    }
  } 
  options.props = res
}

normalizeInject

格式化传入的 inject 数据

function normalizeInject (options, vm) {
  // 没有inject就退出
  const inject = options.inject
  if (!inject) return
 
  const normalized = options.inject = {}
  // 传入的inject 是Array的情况下,把数据格式化成 
  /*
    {
      key: { from: inject[key] }
    }
  */
  if (Array.isArray(inject)) {
    for (let i = 0; i < inject.length; i++) {
      normalized[inject[i]] = { from: inject[i] }
    }
  } else if (isPlainObject(inject)) {
  // inject 是Object类型的时候,依次遍历属性
  // 1. 值为Object格式,则合并对象中所有属性到一个新的对象中
  // 2. 值为 String, 则格式化为 { from: val }
    for (const key in inject) {
      const val = inject[key]
      normalized[key] = isPlainObject(val)
        ? extend({ from: key }, val)
        : { from: val }
    }
  } 
}

normalizeDirectives

格式化自定义指令

function normalizeDirectives (options: Object) {
  const dirs = options.directives
  if (dirs) {

	// 传入的指令格式为Object,把每个指令都遍历出来,只处理传入了单一函数的指令 
	/*
		directives: {
			"v-demo": function(){...}
		}
	*/

    for (const key in dirs) {
      const def = dirs[key]
      // 这里只是检查一下传入的指令是否只有一个函数
      // 如果是的,那么就把bind和update同时指向这个函数
      // 否则就无需格式化
      if (typeof def === 'function') {
        dirs[key] = { bind: def, update: def }
      }
    }
  }
}

经过上面一系列格式化之后,开始合并配置 mergeField

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值