前情提要
今天前端同事反馈一个问题,说日期组件的格式化有异常。本来是日期+时间的格式结果只剩下日期。
于是排查了一下源代码,发现另一个同事在二次开发日期组件时,将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都是会覆盖掉子组件的默认值的。