Vue如何初始化props

183 阅读2分钟

前情提要

今天前端同事反馈一个问题,说日期组件的格式化有异常。本来是日期+时间的格式结果只剩下日期。

于是排查了一下源代码,发现另一个同事在二次开发日期组件时,将format这个props的默认值写成了yyyy:HH:dd。 导致日期时间选择器格式化的值是错误的。但是业务原因又需要添加这个属性上去。

一时间对props默认值跟组件传入值的优先级印象有点模糊。

如果子组件设置了默认值但是父组件给子组件绑定空字符串时,是以默认值优先?还是空字符串优先,绑定undefined或者null呢?

于是我决定看一下vue源码中是如何处理props的。消灭心中这模糊的知识。

源码的位置位于packages/runtime-core/src/componentProps.ts

阅读源码的技巧之一是只关注自己需要的点,因为源码需要处理的功能非常多,所以需要屏蔽掉那些与我们目的无关的内容。顺着执行顺序理清我们关注的代码逻辑。

在这个文件中找到resolvePropValue这个函数,从命名中不难看出这是获取props值的函数,只需要重点关注这个方法中关于默认值以及传入undefined即可。

function resolvePropValue(
  options: NormalizedProps,
  props: Data,
  key: string,
  value: unknown,
  instance: ComponentInternalInstance,
  isAbsent: boolean,
) void {
      const opt = options[key]
      if (opt != null) {
          const hasDefault = hasOwn(opt, 'default') //判断是否有默认值
          if (hasDefault && value === undefined){ // 如果有默认值并且传入的值是undefined
              if (
                opt.type !== Function &&
                !opt.skipFactory &&
                isFunction(defaultValue)
              ){
                  // 判断是否为工厂函数
              }else {
                value = defaultValue // 非工厂函数时将值设置为默认值
              }
          }
      }
}

总结

通过分析代码,可以看出vue在处理props默认值时,会判断组件传入的props的值是否为undefined,若为undefined则触发默认值设置的逻辑,并且判断是否为工厂函数,若不是则直接赋值默认值。 所以在二次开发组件中,若子组件的props的默认值有值,而封装的父组件的props默认值为空字符串或null都是会覆盖掉子组件的默认值的。