vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.69k stars 8.33k forks source link

Warning of `<Transition>` with non-element root/multiple children isn't clear #3338

Open shameleo opened 3 years ago

shameleo commented 3 years ago

Version

3.0.7

Reproduction link

https://jsfiddle.net/7q2gp3L4/

Steps to reproduce

Click "toggle" button

What is expected?

Opacity transition, as slot returns single element

What is actually happening?

Error: "Component inside renders non-element root node that cannot be animated"


This is regression, it worked with ver 3.0.3 and earlier: https://jsfiddle.net/r49yx6pq/ Possible workaround is to make separate components for each case: https://jsfiddle.net/vfk5h1en/, but it would be nice to get rid of it <keep-alive> simply explains why would I need it, it is not necessary for reproduction

posva commented 3 years ago

You need one element at the root of your container for the transition to apply the classes: https://jsfiddle.net/1ax56d9p/

Maybe we should change the wording in the warning:

Component inside <Transition> renders non-element root node that cannot be animated. 
shameleo commented 3 years ago

Yes, I understand this, I thought maybe Vue can check how many elements slot actually returns, because it is always single element in my case. But if not, I'm ok with your workaround. It's strange, though because component have multiple root nodes as well, but Vue handles this and transition on components is allowed. Anyway, if it should stay as it is warning would be more clear if it emphasize that root node cannot be animaned because it potentially can resolve to multiple elements or something like that.

HcySunYang commented 3 years ago

Although we can check whether it is a multi-root with a single element node. However, if Transition can work in this case, then the directives and attr fallthrough should also work in this case.

shameleo commented 3 years ago

I not sure which policy you are talking about. Vue already has dual handling of similar cases. From docs:

When used on components, custom directive will always apply to component's root node, similarly to non-prop attributes. Unlike attributes, directives can't be passed to a different element with v-bind="$attrs". With fragments support, components can potentially have more than one root nodes. When applied to a multi-root component, directive will be ignored and the warning will be thrown.

The same with attributes. And, just for reminder, that is regression, it worked with <=3.0.3 However, that is up to you.

lizyChy0329 commented 2 months ago

vue's multiple root node is very weak, and many situations confuse developers