vue prop不写value的处理逻辑
vue props传递时不写value时的处理
如果父组件传入了该prop
属性,那么需要满足以下几点:
- 该属性值为空字符串或者属性值与属性名相等;
prop
的type
属性中不存在String
类型;- 如果
prop
的type
属性中存在String
类型,那么Boolean
类型在type
属性中的索引必须小于String
类型的索引,即Boolean
类型的优先级更高;
则将该属性值设置为true
经过验证
设C1为组件A,C2为组件B
写法一: props传入的值是空字符串;
props: {
disabled: {
type: [String, Boolean],
default: false,
},
},
写法二: 我们调换type顺序,<C1 disabled/> props传入的值是true;
props: {
disabled: {
type: [Boolean, String],
default: false,
},
},
源码赏析
// src/core/util/props.js
export function validateProp (key,propOptions,propsData,vm) {
const prop = propOptions[key]
const absent = !hasOwn(propsData, key)
let value = propsData[key]
// boolean casting
const booleanIndex = getTypeIndex(Boolean, prop.type)
if (booleanIndex > -1) {
if (absent && !hasOwn(prop, 'default')) {
value = false
} else if (value === '' || value === hyphenate(key)) {
// only cast empty string / same name to boolean if
// boolean has higher priority
const stringIndex = getTypeIndex(String, prop.type)
if (stringIndex < 0 || booleanIndex < stringIndex) {
value = true
}
}
}
// check default value
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') {
assertProp(prop, key, value, vm, absent)
}
return value
}
在这里做一下记录,只有深入原理,开发的时候才更加得心应手。
注意$attrs不传递value时,例如<component disabled/> 当$attrs.disabled拿到的值是"",这符合html attribute特性。
解释如下:
布尔值属性
一些内容属性(例如 required
, readonly
, disabled
)是布尔值属性。如果一个布尔值属性存在,则其值是 true,如果不存在,其值是 false。
HTML5 定义了布尔值属性允许的取值:如果属性存在,其值必须是一个空字符串(即该属性的值未分配),或者是一个大小写无关的 ASCII 字符串,该字符串与属性名严格相同,前后都没有空格。下述例子是为一个布尔值属性取值的几个有效方式。
<div itemscope> This is valid HTML but invalid XML. </div>
<div itemscope=itemscope> This is also valid HTML but invalid XML. </div>
<div itemscope=""> This is valid HTML and also valid XML. </div>
<div itemscope="itemscope"> This is also valid HTML and XML, but perhaps a bit verbose. </div>
再明确一点,布尔值属性不能取值为 "true
" 和 "false
"。如果需要表示 false 值,布尔值属性需要整个忽略不写。这个限制澄清了一些常见误会:比如在元素中设置 checked="false"
,元素的 checked
属性会被解读为 true,因为这个属性出现了。
参考文献
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes
读好书,如同与先哲们交谈。