Unhandled error during execution of scheduler flush when rendering components in a transition group that have a v-if directive
Version
3.2.26
Reproduction link
Steps to reproduce
I am using a transition group as follows:
<transition-group name="foo" tag="div" appear>
...
</transition-group>
Within it, I have a list of custom components. If I apply a v-if
on these components within the parent template, everything works as expected:
<transition-group name="foo" tag="div" appear>
<other-component v-for="item in items" :key="item.id" />
<foo-component key="foo" :foos="foos" v-if="foos.length > 0" />
<bar-component key="bar" :bars="bars" v-if="bars.length > 0" />
</transition-group>
Both foos
and bars
are loaded asynchronously, and the components appear correctly with a transition animation as soon as the items are loaded and available.
However, I tried to refactor this to letting the components load the items themselves, and if I move the v-if
into the child component (still on the outer most HTML element), as follows:
<transition-group name="foo" tag="div" appear>
<other-component v-for="item in items" :key="item.id" />
<!-- now these components load their items themselves, and govern their own appearance with an internal `v-if` -->
<foo-component />
<bar-component />
</transition-group>
This however triggers a series of errors in the console:
Unhandled error during execution of render function
Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next
TypeError: child.el.getBoundingClientRect is not a function
What is expected?
That if using a v-if
inside of a child component which is listed in a transition-group
, this works as expected.
What is actually happening?
The error as above is thrown and v-for
some of the components in the transition group fail to render.
Trying to render components in a transition group and govern their appearance internally in the component instead of externally in the parent component.
To reproduce in the playground, remove the v-if
condition on the Bar.vue component to make the example work, then put it back to trigger the error.
The interesting thing is that this error only seems to occur if you have both the v-for
rendered list of items, and the component with v-if
together in the same transition group.
If you take either of them out, everything works as expected.
Further testing reveals that using v-show
instead of v-if
in the child components does not result in the same problem, so this is an acceptable workaround for now.
@LinusBorg I don't think this is a bug: <transition-group>
should have a child with v-for
only, shouldn't it? Based on that, using transition + transition-group works fine
I don't think v-for
is the problem. The problem is that when a transition-group updates (here: the v-for items where changed), one of the child elements is a component still that has a comment as a placeholder element because of a v-if
inside it.
While TransitionGroup skips comment nodes from direct children (i.e. the div with the v-if
in the transition-group, it fails to properly do so for a child component that itself renders a comment.
Now, we can talk about wether a component in a transition group must always have a root element, but I feel like there may be an actual fix.
Right, but that bar component shouldn’t go in the transition group, it should go in a transition and then it works
Actually it won't, because if I create a nested transition for the bar element or others, then it will break the move transition effect that I have and am using for the group.
Instead, the bar item will transition itself fine, but the rest of the items in the group will just be moved into their new place in an abrupt way without animation.
This is the reason why both the v-for elements and the components with v-if are in the same group. So that once they have loaded their items, all other items in the group make space for the new item elegantly and slide aside.
This is maybe not reflected properly in the fiddle, as I was aiming to reproduce the bug there, not to demonstrate the full use case.
If it's possible to use v-if on the component directly in a transition group, you'd expect it to be allowed to use a v-if on the root element of the component itself too though. It seems to make sense (as long as there is just one root element).
Thanks for looking into this
On Mon, Dec 27, 2021, 01:17 Eduardo San Martin Morote < ***@***.***> wrote:
Right, but that bar component shouldn’t go in the transition group, it should go in a transition and then it works
— Reply to this email directly, view it on GitHub https://github.com/vuejs/vue-next/issues/5168#issuecomment-1001168747, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADXYQVVNTIS3EXTA3EVNQ3US4BTXANCNFSM5KXERRCA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you authored the thread.Message ID: @.***>