0.先抛出个问题
vue的prop里的type类型除了用来校验类型外,还会影响接收的值吗?
举个例子
<template>
<div>
flag:{{flag}}
</div>
</template>
<script>
export default {
props: {
flag: {
type: Boolean,
// type: [String, Boolean],
}
}
}
</script>
这里接收的flag
type类型定义为 Boolean
和定义为[String, Boolean]
或者不定义type
,会对接收的flag
值有影响吗?(文章末尾给答案)
1.背景
前几天,在项目中碰到一个props传值问题。
父组件
<template>
// 实际项目上,flag值通过一些逻辑计算获得的(这里为了方便,写成空字符串)
<SubComponentVue flag=""/>
</template>
<script>
import SubComponentVue from "../components/SubComponent.vue"
export default {
components: {
SubComponentVue
}
}
</script>
子组件
<template>
<div>
// 子组件用 flag 做一些逻辑判断
flag:{{flag}}
</div>
</template>
<script>
export default {
props: {
flag: {
type: Boolean,
}
}
}
</script>
此时子组件props接收的
flag
的值是多少呢? 相信很多小伙伴会回答是空字符串
或false
。 实际上是true
,想不到吧🙈
2. 查看vue源码是如何处理prop
带着上面的疑惑,查看了下vue(2.6.11
)源码是如何处理prop的
export function validateProp (
key: string,
propOptions: Object,
propsData: Object,
vm?: Component
): any {
const prop = propOptions[key]
const absent = !hasOwn(propsData, key)
let value = propsData[key]
// 检测type里有没有定义Boolean类型
const booleanIndex = getTypeIndex(Boolean, prop.type)
// 如果检测到type里有定义Boolean类型,走if里面逻辑
if (booleanIndex > -1) {
if (absent && !hasOwn(prop, 'default')) {
// 父组件没传值 且 没定义默认值,返回false
value = false
} else if (value === '' || value === hyphenate(key)) {
// 父组件传''空字符串
// 或者 以<SubComponentVue flag/>这种方式传 ,
const stringIndex = getTypeIndex(String, prop.type)
// 考虑type有传多个值的情况:
// 如果不包含String类型,则返回true
// 如果包含String类型, 但 Boolean类型在String类型的前面,也返回true. 比如:type: [Boolean, String],
if (stringIndex < 0 || booleanIndex < stringIndex) {
value = true
}
}
}
// 以上情况都不满足时,如果父组件没传值,取默认值
if (value === undefined) {
value = getPropDefaultValue(vm, prop, key)
// since the default value is a fresh copy,
// make sure to observe it.
const prevShouldObserve = shouldObserve
toggleObserving(true)
observe(value)
toggleObserving(prevShouldObserve)
}
if (
process.env.NODE_ENV !== 'production' &&
// skip validation for weex recycle-list child component props
!(__WEEX__ && isObject(value) && ('@binding' in value))
) {
assertProp(prop, key, value, vm, absent)
}
// 以上情况都不满足时,取父组件传的值
return value
}
发现vue源码里对type为Boolean
类型做了特殊处理(具体分析注释在上面的代码里
)。
3. 先回答下文章开头的问题:
vue的prop里的type类型除了用来校验类型外,还会影响接收的值吗?
答案是: 会
4. 总结
prop传值问题
-
- 如果子组件props接收的type
包含Boolean
类型,- 1.1 父组件
没传值
且没定义默认值
,返回false
- 1.2 父组件传
''空字符串
或者 以<SubComponentVue flag/>
这种方式传- 1.2.1 如果
不包含String类型
,则返回true
. - 1.2.2 如果包含String类型, 但
Boolean类型在String类型的前面
,也返回true
. 比如:type: [Boolean, String]
- 1.2.1 如果
- 1.1 父组件
- 如果子组件props接收的type
-
-
以上的条件不满足时,则父组件传什么值,子组件就会接收什么值。父组件不传值,子组件就取
default默认值
, 没有定义默认值的话,返回undefined
-