Skip to content
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

TransitionGroup doesn't render a wrapper element by default in Vue 3, it uses a Fragment #648

Closed
crutch12 opened this issue Oct 24, 2020 · 12 comments · Fixed by #649
Closed
Labels
enhancement New feature or request

Comments

@crutch12
Copy link

crutch12 commented Oct 24, 2020

What problem does this feature solve?

I suddenly found out that vue2 <TransitionGroup/> component transforms into <span/> tag.

Vue2:

<TransitionGroup name="vue2" class="vue2-class">
  <span key="1" class="class-1">1</span>
  <span key="2" class="class-2">2</span>
</TransitionGroup>

compiles to

<span class="vue2-class">
  <span class="class-1">1</span>
  <span class="class-2">2</span>
</span>

Meanwhile vue3 <TransitionGroup/> doesn't create element in DOM, so it breaks previous behaviour and old code.

Vue3:

<TransitionGroup name="vue3" class="vue3-class">
  <span key="1" class="class-1">1</span>
  <span key="2" class="class-2">2</span>
</TransitionGroup>

compiles to

<span class="class-1">1</span>
<span class="class-2">2</span>

Also Vue3:

<TransitionGroup name="vue3" class="vue3-class">
  <span key="1" class="class-1">1</span>
</TransitionGroup>

compiles to

<span class="class-1 vue3-class">1</span>

It moves classes from <TransitionGroup/> to single child.

What does the proposed API look like?

We should add this info to vue3 migration guide (maybe here: https://v3.vuejs.org/guide/migration/transition.html#overview)

The fastest way to migrate: wrap your <TransitionGroup/> with new <span/>:

Before:

<TransitionGroup name="vue2" class="vue2-class">
  <span key="1" class="class-1">1</span>
  <span key="2" class="class-2">2</span>
</TransitionGroup>

After:

<span class="vue3-class">
  <TransitionGroup name="vue3">
    <span key="1" class="class-1">1</span>
    <span key="2" class="class-2">2</span>
  </TransitionGroup>
</span>

UPD:

Checked vue2 docs: https://v3.vuejs.org/guide/transitions-list.html#list-transitions
And vue3 docs: https://v3.vuejs.org/guide/transitions-list.html#list-transitions

Unlike <transition>, it renders an actual element: a <span> by default. You can change the element that's rendered with the tag attribute.

So it looks like a vue3 <transition-group/> bug. Or v3 docs are wrong.

The fastest way to fix your code: add tag="span" to <transition-group/>

@crutch12 crutch12 changed the title TransitionGroup tag (span) behaviour has changed TransitionGroup tag (span) behaviour has changed - update docs Oct 24, 2020
@LinusBorg
Copy link
Member

Moving this to the docs repo

@LinusBorg LinusBorg transferred this issue from vuejs/core Oct 24, 2020
@crutch12
Copy link
Author

crutch12 commented Oct 24, 2020

@LinusBorg found out this is a bug :D
Checked vue3 docs: https://v3.vuejs.org/guide/transitions-list.html#list-transitions

Unlike <transition>, it renders an actual element: a <span> by default. You can change the element that's rendered with the tag attribute.

And it doesn't render <span> by default

Or this is a vue3 docs bug

@LinusBorg
Copy link
Member

LinusBorg commented Oct 24, 2020

It's a docs issue. Since we have Fragments support in Vue 3, we don't need a root element anymore for TransitionGroup. You can have one created by defining it with the tag prop though, which was previously used in Vue 2 to use another element than the default span:

<TransitionGroup tag="span" name="vue2" class="vue2-class">
  <span key="1" class="class-1">1</span>
  <span key="2" class="class-2">2</span>
</TransitionGroup>

Relevant code:

https://github.com/vuejs/vue-next/blob/ea5f92ae051be511558569eaf4c2afa2839c3e4d/packages/runtime-dom/src/components/TransitionGroup.ts#L101

@LinusBorg LinusBorg changed the title TransitionGroup tag (span) behaviour has changed - update docs TransitionGroup doesn't render a wrapper element by default in Vue 3, it uses a Fragment Oct 24, 2020
@crutch12
Copy link
Author

@LinusBorg yeah, I see, already updated issue description

@LinusBorg LinusBorg linked a pull request Oct 24, 2020 that will close this issue
crutch12 added a commit to crutch12/vue-ctk-date-time-picker that referenced this issue Oct 24, 2020
@raukaute
Copy link

When rendering server-side only children of <transition-group> will be rendered, and the tag is replaced by Fragment. This totally makes sense performance wise, but leads to mismatch on client hydration. Is this relevant here, or should it be an issue on it's own?

@LinusBorg
Copy link
Member

LinusBorg commented Oct 27, 2020

I don't see how that should lead to a hydration mismatch? I think I don't get what you mean

@raukaute
Copy link

Admittedly (my bad), it's not the exact same case as you were talking about the default when no tag prop is passed to TransitionGroup.
However, if we do and instead of the desired tag we get a Fragment (i.e. <!--[--><!--]-->) then this will cause a mismatch in the hydration process on the client (comparing start of fragment <!--[--> to <desired-tag>) Please correct me if I'm wrong, but in the end that's when the console keeps telling me.
Here's a basic reproduction of what I mean.

@LinusBorg
Copy link
Member

LinusBorg commented Oct 28, 2020

However, if we do and instead of the desired tag we get a Fragment (i.e. )

That's the part I'm having trouble understanding. I'd like a reproduction of that actually happening during SSR. If that's the case, open an issue with that reproduction in the vue-next repo.

We obviously do now knowingly offer APIs that break SSR.

@raukaute
Copy link

Thanks for the prompt answer. I will follow your advice and open an issue over in the vue-next repo.

We obviously do now knowingly offer APIs that break SSR.

Can you give an example?

@LinusBorg
Copy link
Member

LinusBorg commented Oct 28, 2020

You gave an example. You claim that during SSR, TransitionGroup, if provided with a tag prop, still renders a fragment, but on the client it renders a wrapper element.

If that was implemented this way knowingly by us, we would have coded something that will always break hydration. Of course we won't do such a thing, so if what you claim is true, it's a bug, not a documentation issue.

@raukaute
Copy link

Ah I got you. I think instead of 'now' you mean 'not'.

@LinusBorg
Copy link
Member

Oh. Right. 🙈

sdras added a commit that referenced this issue Oct 31, 2020
* feat(migration): transition-group
document fragment default behaviour

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/transitions-list.md

* Update src/guide/migration/transition-group.md

* add transition-group to config

Co-authored-by: Thorsten Luenborg <t.luneborg@googlemail.com>
Co-authored-by: Sarah Drasner <sarah.drasner@gmail.com>
nick-lai pushed a commit to nick-lai/docs-next that referenced this issue Dec 2, 2020
* feat(migration): transition-group
document fragment default behaviour

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/migration/transition-group.md

* Update src/guide/transitions-list.md

* Update src/guide/migration/transition-group.md

* add transition-group to config

Co-authored-by: Thorsten Luenborg <t.luneborg@googlemail.com>
Co-authored-by: Sarah Drasner <sarah.drasner@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants