炫意html5
最早CSS3和HTML5移动技术网站之一

[Vue.js 3.0] Migration – Attribute Coercion Behavior

# Attribute Coercion Behavior


breaking

Info

This is a low-level internal API change and does not affect most developers.

# Overview

Here is a high level summary of the changes:

  • Drop the internal concept of enumerated attributes and treat those attributes the same as normal non-boolean attributes
  • BREAKING: No longer removes attribute if value is boolean false. Instead, it’s set as attr=”false” instead. To remove the attribute, use null or undefined.

For more information, read on!

# 2.x Syntax

In 2.x, we had the following strategies for coercing v-bind values:

  • For some attribute/element pairs, Vue is always using the corresponding IDL attribute (property): like value of <input>, <select>, <progress>, etc(opens new window).

  • For “boolean attributes(opens new window)” and xlinks(opens new window), Vue removes them if they are “falsy” (undefined, null or false(opens new window)) and adds them otherwise (see here(opens new window) and here(opens new window)).

  • For “enumerated attributes(opens new window)” (currently contenteditable, draggable and spellcheck), Vue tries to coerce(opens new window) them to string (with special treatment for contenteditable for now, to fix vuejs/vue#9397(opens new window)).

  • For other attributes, we remove “falsy” values (undefined, null, or false) and set other values as-is (see here(opens new window)).

The following table describes how Vue coerce “enumerated attributes” differently with normal non-boolean attributes:

Binding expression foo normal draggable enumerated
: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"

We can see from the table above, current implementation coerces true to 'true' but removes the attribute if it’s false. This also led to inconsistency and required users to manually coerce boolean values to string in very common use cases like aria-* attributes like aria-selected, aria-hidden, etc.

# 3.x Syntax

We intend to drop this internal concept of “enumerated attributes” and treat them as normal non-boolean HTML attributes.

  • This solves the inconsistency between normal non-boolean attributes and “enumerated attributes”
  • It also makes it possible to use values other than 'true' and 'false', or even keywords yet to come, for attributes like contenteditable

For non-boolean attributes, Vue will stop removing them if they are false and coerce them to 'false' instead.

  • This solves the inconsistency between true and false and makes outputting aria-* attributes easier

The following table describes the new behavior:

Binding expression foo normal draggable enumerated
: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=""

†: changed

Coercion for boolean attributes is left untouched.

# Migration Strategy

# Enumerated attributes

The absence of an enumerated attribute and attr="false" may produce different IDL attribute values (which will reflect the actual state), described as follows:

Absent enumerated attr IDL attr & value
contenteditable contentEditable'inherit'
draggable draggablefalse
spellcheck spellchecktrue

To keep the old behavior work, and as we will be coercing false to 'false', in 3.x Vue developers need to make v-bind expression resolve to false or 'false' for contenteditable and spellcheck.

In 2.x, invalid values were coerced to 'true' for enumerated attributes. This was usually unintended and unlikely to be relied upon on a large scale. In 3.x true or 'true' should be explicitly specified.

# Coercing false to 'false' instead of removing the attribute

In 3.x, null or undefined should be used to explicitly remove an attribute.

# Comparison between 2.x & 3.x behavior

Attribute v-bind value 2.x v-bind value 3.x HTML output
2.x “Enumerated attrs”
i.e. contenteditable, draggable and spellcheck.
undefined, false undefined, null removed
true, 'true', '', 1,
'foo'
true, 'true' "true"
null, 'false' false, 'false' "false"
Other non-boolean attrs
eg. aria-checked, tabindex, alt, etc.
undefined, null, false undefined, null removed
'false' false, 'false' "false"

炫意HTML5 » [Vue.js 3.0] Migration – Attribute Coercion Behavior

CSS3教程HTML5教程