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

transition-group throws error attempting to transition whitespace node, but only with migration build and client-side compiled template #4622

Closed
catrope opened this issue Sep 17, 2021 · 4 comments · Fixed by #9421
Labels
has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working scope: transition scope: v2 compat

Comments

@catrope
Copy link
Contributor

catrope commented Sep 17, 2021

Version

3.2.11

Reproduction link

codesandbox.io

Steps to reproduce

  • Load the CodeSandbox link. Open the CodeSandbox console (using the console link in the bottom left corner of the preview area) and note that a warning about <TransitionGroup> has already appeared.
  • Click the "Toggle transition" button

What is expected?

The transition works (the hidden image appears)

What is actually happening?

An error is thrown when attempting the transition (child.el.getBoundingClientRect is not a function), and the transition doesn't work. Additionally, a warning is thrown on load (<TransitionGroup> children must be keyed)


This issue is related to #4621, but it's a much more bizarre version of it. All of the following conditions must be met to reproduce the bug:

  • A <transition-group> that contains two elements, separated by whitespace, with the first element initially hidden using v-if and the second element always shown. Unhiding the first element triggers the error.
  • The migration build (@vue/compat) must be used; the bug doesn't happen if you use the regular non-migration build (vue)
  • The component containing the <transition-group> must be compiled on the client side. The bug doesn't happen if this component is pre-compiled on the server side. (To make client-side compilation work, the full build must be used rather than the runtime-only build.)

Like in #4621, the bug happens because the TransitionGroup code tries to process a text node as one of the nodes being transitioned, in this case the text node between the two <p> elements. Text nodes don't have a .getBoundingClientRect() method, which is what causes the error. The warning about TransitionGroup children needing to be keyed is also caused by the text node (it's checked for a key, and it doesn't have one).

In the real-world use case that revealed this bug (see https://phabricator.wikimedia.org/T289019#7322619 ), the <transition-group> has tag="div" set, one of the children is a component instead of a plain tag, and the <transition-group> is nested inside a <transition> via another component's slot, but those things don't appear to matter, so I've removed them to simplify the (already complex) minimal reproduction.

@catrope
Copy link
Contributor Author

catrope commented Sep 20, 2021

It looks like these confusing conditions (only in the migration build and with client-side compilation) are not actually necessary, but instead it looks like this bug is triggered by compilerOptions.whitespace being set to 'preserve' (which the migration build does, for client-side compiled templates). The text node that causes this bug is only created when whitespace is set to 'preserve', and is not created when whitespace is set to 'collapse'.

@posva
Copy link
Member

posva commented Oct 12, 2021

as a temporary workaround you can remove the HTML comment before the <p v-if="..."> the whitespace between the two p nodes

@catrope
Copy link
Contributor Author

catrope commented Oct 12, 2021

Apologies, it looks like I accidentally messed up the CodeSandbox; it should be correct now. The template code that triggers this bug is:

  <button @click="showImage = !showImage">Toggle transition</button>
  <transition-group name="foo-bar" class="foo-bar">
    <p key="hello">Hello</p>
    <p key="img" v-if="showImage">Image</p>
  </transition-group>

@catrope
Copy link
Contributor Author

catrope commented Oct 12, 2021

In other words, it fails even without using comments anywhere. Just the text node in between the two <p> tags is enough to cause this failure.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working scope: transition scope: v2 compat
Projects
None yet
3 participants