core icon indicating copy to clipboard operation
core copied to clipboard

:class="undefined" causes class being rendered

Open wenfangdu opened this issue 4 years ago • 16 comments

Version

3.2.6

Steps to reproduce

<template>
  <div :title="undefined" :class="undefined" :style="undefined">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore molestiae quod voluptas
    reprehenderit possimus nihil eligendi iure et esse aut, iste natus porro enim rerum cumque
    veniam quae! Quam, voluptatum.
  </div>
</template>

What is expected?

None of title, class, style should be rendered.

What is actually happening?

class is rendered, the same thing applies to null.

Additional info

This was fixed in v3.1.5 but is reproducible when using the latest commit.

wenfangdu avatar Feb 06 '21 01:02 wenfangdu

I don’t think this is a bug, but it’s reasonable to optimize that behavior.

HcySunYang avatar Feb 06 '21 02:02 HcySunYang

@HcySunYang

<template>
  <div :style="false" :class="false" :foo="false">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium modi
    repudiandae, illum sequi nemo est deleniti optio distinctio quaerat quasi
    dolores vitae aspernatur quisquam, voluptatibus quibusdam ullam, ipsum aut
    amet?
  </div>
</template>

If isButtonDisabled has the value of null, undefined, or false, the disabled attribute will not even be included in the rendered .

In vue ^2.6.10, the above code will render class too, could you please make a PR regarding that?

wenfangdu avatar Feb 06 '21 02:02 wenfangdu

Check out the new attributes coercion behavior https://github.com/vuejs/rfcs/blob/master/active-rfcs/0024-attribute-coercion-behavior.md

HcySunYang avatar Feb 06 '21 02:02 HcySunYang

@HcySunYang Yes, I've known that, I guess this issue belongs to the vue 2 repo, I've created one there (https://github.com/vuejs/vue/issues/11902).

Also,

If the bound value is null or undefined then the attribute will not be included on the rendered element.

The documented behavior is class wouldn't be rendered if it's null or undefined, so I think it is a bug.

wenfangdu avatar Feb 06 '21 03:02 wenfangdu

I think this was for performance reasons. There are no practical reasons to not remove class and it was highlighted in other issues in Vue 2 and dismissed already. Definitely not a bug but worth checking if the perf implication still exists

posva avatar Feb 06 '21 15:02 posva

Only call removeAttribute when the element does not have any class. In other cases, className is used. I think it's fine.

HcySunYang avatar Feb 06 '21 15:02 HcySunYang

I think this should be reopend as the fix in 7013e8f does not work. Problem is the value argument of patchClass is never null because all class values (including null, undefined etc) are converted into strings using normalizeClass by the compiler

Liwoj avatar Aug 24 '21 10:08 Liwoj

@Liwoj Just tried, reproducible for me as well. Ping @yyx990803

wenfangdu avatar Aug 24 '21 12:08 wenfangdu

@Liwoj Just tried, reproducible for me as well. Ping @yyx990803

I made a repro

the value is empty string not null image

edison1105 avatar Aug 24 '21 13:08 edison1105

@edison1105 For :class="undefined" and :class="null", @vue/runtime-dom v3.1.5 removed it, whereas @vue/runtime-dom v3.2.4 kept it, which seems like a regression bug.

wenfangdu avatar Aug 26 '21 01:08 wenfangdu

@edison1105 For :class="undefined" and :class="null", @vue/runtime-dom v3.1.5 removed class, whereas @vue/runtime-dom v3.2.4 kept it, which seems like a regression bug.

Good catch. Would you mind commit a new issue with a working repro?

edison1105 avatar Aug 26 '21 03:08 edison1105

@edison1105 I've updated the issue to reflect that, since the playground doesn't seem to keep the vue version, I included the repro for the latest commit.

wenfangdu avatar Aug 26 '21 05:08 wenfangdu

The issue is that normalizeClass will always coerce the :class value to a string.

https://github.com/vuejs/vue-next/blob/cac6ab5bdb712a3872dfa2b1cd4751d80cb4f38c/packages/shared/src/normalizeProp.ts#L65-L66

and patchClass will only remove the attribute when it's nullish:

https://github.com/vuejs/vue-next/blob/cac6ab5bdb712a3872dfa2b1cd4751d80cb4f38c/packages/runtime-dom/src/modules/class.ts#L16-L17

LinusBorg avatar Sep 17 '21 09:09 LinusBorg

The issue still exists, does anyone have any solution?

https://github.com/vuejs/rfcs/blob/master/active-rfcs/0024-attribute-coercion-behavior.md#drawbacks https://vuejs.org/guide/essentials/template-syntax.html#attribute-bindings

when I use null, empty class property remains in the tag.

Vue version: 3.3.4

gokaybiz avatar Sep 07 '23 17:09 gokaybiz

I have a recursive component, and I want to display the class MyComponent only in the outermost layer. However, this error causes the inner component HTML tags to all become <span class>

So, are there any other solutions?

lisonge avatar Mar 04 '25 02:03 lisonge