Subscribe on changes!

Vue drops `value=""` from `<button>`

avatar
Jul 15th 2022

Vue version

3.2.37

Link to minimal reproduction

SFC Playground

Steps to reproduce

Visit testcase

What is expected?

Both buttons should have a green outline (applied on button[value])

What is actually happening?

The button inside the Vue app does not have a value attribute after Vue renders.

System Info

No response

Any additional comments?

This seems too basic to have gone undetected, so sorry if I'm missing something obvious!

avatar
Jul 17th 2022

vue doesn't add the value attribute to the element if its empty .(edited) ( see https://github.com/vuejs/core/issues/6277#issuecomment-1187714777 for more correct analysis)

<button id="a" value=''  disabled=''></button> 

renders to

<button id="a" disabled=''>

and so the css selector of button[value] is falsy

There are however workarounds, for this less common use case.

for example

<button :value.attr="''" ></button>

which forced binding the attribute, and it can not be removed anymore based on value.

playground

avatar
Jul 18th 2022

Yeah, :value.attr="``" is what I ended up doing, but it seems strange to have to use Vue specific stuff to preserve markup in an element that never even had any Vue attributes or expressions in the first place. I knew that Vue removes attributes when the value is null, but not when it is "". Furthermore, empty attributes do appear to be preserved in other cases, e.g. <img src="" alt="" />, which seems inconsistent.

avatar
Jul 18th 2022

here is the reassessed relevant general logic vue follows.

1. if the attribute name exists as an element prop, set the element prop. 2. if the value is null, remove the attribute ( empty string should not remove attribute, with the exception of prop with a number type) 3. when the attribute name is value there is an additional logic. Only set the prop when the provided value is different than the existing prop value 4. setting an element prop may be expressed as an element attribute

in the case of the <button> the default value of the value prop is an empty '' string based on rule(3) and rule(4) the prop is not going to be set, and the attribute is not going to be shown

This is what creates the apparent inconsistency. for value attribute and other known element attributes.

thankfully forcing setting as explicit attribute exists and can be used as the workaround.

it can be fixed on vue side, by explicitly setting value prop, for empty string, even if the value is the same.

playground: initial non empty prop value - works

avatar
Feb 7th 2023

I get this also with a hidden field:

<input :name="name" value="" type="hidden" />

name and value are props to the component that holds this template. Renders as just:

<input name="my_field" type="hidden">

Didn't use to do this under Vue 2. The :value.attr="''" trick works. With that in place I correctly get this like I did for Vue 2:

<input name="my_field" value="" type="hidden">