属性强制转换行为 重大变更
信息
这是一个低级的内部 API 变更,不会影响大多数开发者。
概述
以下是变更的高级概述
- 删除枚举属性的内部概念,并将这些属性与正常的非布尔属性相同对待
- 重大变更: 如果值为布尔值
false
,不再移除属性。相反,它将设置为 attr="false"。要移除属性,请使用null
或undefined
。
有关更多信息,请继续阅读!
2.x 语法
在 2.x 中,我们有以下策略来强制转换 v-bind
值
对于某些属性/元素对,Vue 始终使用相应的 IDL 属性(property):例如
<input>
的value
,<select>
,<progress>
等.对于 "布尔属性" 和 xlinks,如果它们是“假值”(
undefined
,null
或false
),Vue 会移除它们,否则会添加它们(参见 这里 和 这里)。对于 "枚举属性"(目前是
contenteditable
,draggable
和spellcheck
),Vue 尝试将它们强制转换为字符串(目前对contenteditable
有特殊处理,以修复 vuejs/vue#9397)。对于其他属性,我们移除“假值”(
undefined
,null
或false
)并将其他值按原样设置(参见 这里)。
下表描述了 Vue 如何使用不同的方法来强制转换“枚举属性”和正常的非布尔属性
绑定表达式 | foo 正常 | draggable 枚举 |
---|---|---|
:attr="null" | - | draggable="false" |
:attr="undefined" | - | - |
:attr="true" | foo="true" | draggable="true" |
:attr="false" | - | draggable="false" |
:attr="0" | foo="0" | draggable="true" |
attr="" | foo="" | draggable="true" |
attr="foo" | foo="foo" | draggable="true" |
attr | foo="" | draggable="true" |
从上表可以看出,当前实现将 true
强制转换为 'true'
,但如果它是 false
,则会移除属性。这也导致了不一致,并要求用户在非常常见的用例中(如 aria-*
属性,例如 aria-selected
,aria-hidden
等)手动将布尔值强制转换为字符串。
3.x 语法
我们打算删除“枚举属性”的这个内部概念,并将它们视为正常的非布尔 HTML 属性。
- 这解决了正常非布尔属性和“枚举属性”之间的不一致
- 它还使得能够使用除
'true'
和'false'
之外的值,甚至可以使用尚未出现的关键字,用于诸如contenteditable
之类的属性
对于非布尔属性,Vue 将不再移除它们,如果它们是 false
,则会将它们强制转换为 'false'
。
- 这解决了
true
和false
之间的不一致,并使输出aria-*
属性变得更容易
下表描述了新的行为
绑定表达式 | foo 正常 | draggable 枚举 |
---|---|---|
:attr="null" | - | - * |
:attr="undefined" | - | - |
:attr="true" | foo="true" | draggable="true" |
:attr="false" | foo="false" * | draggable="false" |
:attr="0" | foo="0" | draggable="0" * |
attr="" | foo="" | draggable="" * |
attr="foo" | foo="foo" | draggable="foo" * |
attr | foo="" | draggable="" * |
*: 已变更
布尔属性的强制转换保持不变。
迁移策略
枚举属性
枚举属性的缺失和 attr="false"
可能会产生不同的 IDL 属性值(这将反映实际状态),描述如下
缺失的枚举属性 | IDL 属性 & 值 |
---|---|
contenteditable | contentEditable → 'inherit' |
draggable | draggable → false |
spellcheck | spellcheck → true |
由于我们在 3.x 中不再将 null
强制转换为“枚举属性”的 'false'
,因此在 contenteditable
和 spellcheck
的情况下,开发者需要将那些以前解析为 null
的 v-bind
表达式更改为解析为 false
或 'false'
,以保持与 2.x 相同的行为。
在 2.x 中,无效的值被强制转换为枚举属性的 'true'
。这通常是无意的,并且不太可能在很大程度上被依赖。在 3.x 中,应该明确指定 true
或 'true'
。
将 false
强制转换为 'false'
而不是移除属性
在 3.x 中,应该使用 null
或 undefined
来明确移除属性。
2.x 和 3.x 行为之间的比较
属性 | v-bind 值 2.x | v-bind 值 3.x | HTML 输出 |
---|---|---|---|
2.x “枚举属性” 例如 contenteditable ,draggable 和 spellcheck 。 | undefined | undefined ,null | 已移除 |
true ,'true' ,'' ,1 ,'foo' | true ,'true' | "true" | |
null ,false ,'false' | false ,'false' | "false" | |
其他非布尔属性 例如 aria-checked ,tabindex ,alt 等。 | undefined ,null ,false | undefined ,null | 已移除 |
'false' | false ,'false' | "false" |
ATTR_FALSE_VALUE
ATTR_ENUMERATED_COERCION