-
Notifications
You must be signed in to change notification settings - Fork 4.7k
HTML5 Boolean Attributes #1972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'll preface this by saying that I'm not opposed to this request per se. However, the problem as you describe it does not exist in Vue 3 anymore for the most part. Vue 3 already handles boolean attributes as described by the spec correctly, as in: HTML attributes that are defined as boolean attributes in the spec (like input's All other attributes (and that includes any custom attributes not defined in the spec) will render boolean values as Concerning custom elements, this can be a bit annoying, but if their implementation follows the recommended best practices, they accept attributes as DOM properies as well, so you can use the But there's a catch, namely that the For this, a .boolean flag would be useful and could be discussed. However this really limits the scope of the request to "Custom attributes that I want to treat like boolean attributes for easier selection in CSS". Here's a Playground demonstrating all of the above. |
Thanks for the overview, that's very helpful. I definitely see what you mean regarding the limited utility of a Perhaps the best course of action, at least in the short term, is to update the documentation for "Vue and Web Components" (https://vuejs.org/guide/extras/web-components.html#building-custom-elements-with-vue) to clarify how the Thanks again for your help. |
Sure, docs contributions are welcome. I'd suggest opening an issue on |
Hello, are there any updates about this issue ? |
i am trying to understand in detail vue's handling of the property/attribute duality when it comes to custom elements and booleans. the docs say:
so i have a custom element myElement.myBool === false
myElement.hasAttribute("my-bool") === false
myElement.myBool = true
myElement.hasAttribute("my-bool") === true
myElement.removeAttribute("my-bool")
myElement.myBool === false if i render this in vue: <my-element :my-bool="false" /> the html output is: <my-element my-bool="false"></my-element> i'm curious how it ends up setting the attribute in this case, since example code for such an elementexport class MyElement extends HTMLElement {
#shadow
static observedAttributes = ["my-bool"]
get myBool() {
return this.hasAttribute("my-bool")
}
set myBool(value) {
this.toggleAttribute("my-bool", value)
}
attributeChangedCallback(attrName, oldVal, newVal) {
this.#render()
}
constructor() {
super()
this.#shadow = this.attachShadow({ mode: "open" })
}
connectedCallback() {
this.#render()
}
#render() {
this.#shadow.innerHTML = this.myBool.toString()
}
}
if (!customElements.get("my-element")) {
customElements.define("my-element", MyElement)
} |
ok, i've found the code where the check is done: https://github.com/vuejs/core/blob/04d2c05054c26b02fbc1d84839b0ed5cd36455b6/packages/runtime-dom/src/patchProp.ts#L131 stepping through the code, it seems that the property check is done before the camel case conversion. this seems odd, incorrect even, to me? AFAIK no properties in HTML use kebab-case, nor would i expect any custom elements to have kebab case property names, so it's weird to check for this. if vue defaults to attempting to set properties, but conversely recommends kebab-case for property names in templates, i feel that the i think many of the issues around booleans would go away if this were changed. but i don't fully understand the implications of such a change! i would be interested to hear others' thoughts on this, particularly @LinusBorg |
What problem does this feature solve?
According to the HTML5 spec:
- https://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
For several reasons, especially using Custom Elements / Web Components, it would be helpful to be able to set attributes without corresponding values, in order to comply with the standard. For example,
<input :disabled="true">
should generate<input disabled>
not<input disabled="true"
.<input :disabled="false">
should generate<input>
not<input disabled="false">
.It seems that
<input :disabled="isDisabled ? '' : null">
gets close (correctly handing the false case), but this still generates<input disabled="">
in the true case.What does the proposed API look like?
This exact issue was discussed back in 2016, for Vue 2 (See vuejs/vue#2169). The decision was to add a
.boolean
modifier tov-bind
.In the above example, you could then write
<input :disabled.boolean="true">
which would generate<input disabled>
and<input :disabled.boolean="false">
which would generate<input>
.Has this change, or an equivalent one, made it into Vue 3? If not, and the decision made in 2016 still makes sense, I'm happy to contribute a PR.
The text was updated successfully, but these errors were encountered: