Vue: Merged class attributes are not preserved when a component is created from a render function and the root node has a class binding

Created on 15 May 2018  路  4Comments  路  Source: vuejs/vue

Version

2.5.16

Reproduction link

https://jsfiddle.net/jmabj70u/

updated: added child-compoent directly to compare expected vs actual results

https://jsfiddle.net/jmabj70u/1/

Steps to reproduce

  1. Create a component that render its content through a render function and render a child component with a static class attribute
  2. In the child component, add a class binding to the root element
  3. When the class binding is applied (for example, when a condition becomes true) the static classes passed from the parent component render function is lost

What is expected?

That the child component keeps both the static and dynamic classes

What is actually happening?

Only the dynamic classes added through the v-bind:class are kept in the root element


I looked through other issues reporting similar behaviors, the one more likely to be related is issue #1014 , but this one differs from that case since any of the components here are functional components.

updated: actual issue is https://github.com/vuejs/vue-loader/issues/1014#issuecomment-338281037 see comment below

The example in the fiddle is a simplified version to showcase the problem. In my use-case, the parent component can render a different child component depending on a prop or state, the parent acts as a "proxy" or "polymorphic" component for several different children.

Most helpful comment

That is no longer the case though, it is now documented (https://vuejs.org/v2/guide/render-function.html#Passing-Attributes-and-Events-to-Child-Elements-Components). But that's for functional components

In your case you should either use class or staticClass, not attrs:

   return createElement( 'child-component', {
         class: {
            big: true
         }
     }, this.$slots.default );

More at https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth

All 4 comments

An update, the issue I mentioned is #1014 but from vue-loader, pelase see the link below

https://github.com/vuejs/vue-loader/issues/1014#issuecomment-338281037

Sorry for the lack of attention

That is no longer the case though, it is now documented (https://vuejs.org/v2/guide/render-function.html#Passing-Attributes-and-Events-to-Child-Elements-Components). But that's for functional components

In your case you should either use class or staticClass, not attrs:

   return createElement( 'child-component', {
         class: {
            big: true
         }
     }, this.$slots.default );

More at https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth

Hi @posva , thanks for the feedback.

I couldn't find in any part of the guide or the API any reference of the staticClass usage.

Do you want me to make a PR adding this info on the guide?

Thank you but let's keep it how it is, I'm not sure if it was more of an internal property, people should use the class one instead 馃檪

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wenLiangcan picture wenLiangcan  路  39Comments

eu81273 picture eu81273  路  40Comments

yyx990803 picture yyx990803  路  210Comments

ShuvoHabib picture ShuvoHabib  路  40Comments

yyx990803 picture yyx990803  路  36Comments