Vue: Error thrown when using transition-group with conditionally rendered children

Created on 18 Jul 2018  ·  11Comments  ·  Source: vuejs/vue

Version

2.5.16

Reproduction link

https://codepen.io/riophae/pen/EpgWdZ

Steps to reproduce

  1. Open the pen and it shows 1, 3, 5
  2. Click the button

What is expected?

It should show 3, 5

What is actually happening?

Got this error in console:

[Vue warn]: Error in render: "TypeError: c$1.elm.getBoundingClientRect is not a function"

found in

---> <TransitionGroup>
       <Root>

TypeError: c$1.elm.getBoundingClientRect is not a function
   at Proxy.render (VM643 vue.js:8383)
   at VueComponent.Vue._render (VM643 vue.js:4535)
   at VueComponent.updateComponent (VM643 vue.js:2788)
   at Watcher.get (VM643 vue.js:3140)
   at Watcher.run (VM643 vue.js:3217)
   at flushSchedulerQueue (VM643 vue.js:2981)
   at Array.<anonymous> (VM643 vue.js:1839)
   at MessagePort.flushCallbacks (VM643 vue.js:1760)
transition

Most helpful comment

The transition try to modify an element from the v-for that is not rendered because of the v-if. You can use v-show instead of v-if to render the element. The best solution for me would be to filter the list in a computed property and give the filtered list in your v-for.

All 11 comments

The transition try to modify an element from the v-for that is not rendered because of the v-if. You can use v-show instead of v-if to render the element. The best solution for me would be to filter the list in a computed property and give the filtered list in your v-for.

@maxirozay Hi Maxime, thanks for your reply.

My actual use case is that, I was not rendering a list inside <transition-group />, but some different components . And I was not using template but JSX. So there is no v-if or v-show. I was conditionally rendering the children using if statement in the child component's render function. When I didn't want to show the compent, I returned null in its return function. So I should try change that to set display: none.

But I still think it would be better for Vue to be able to handle cases like mine, since my code is very normal and not doing anything wrong :) Anyway, with display: none it should work.

You're welcome Fangzhou.

display: none should work. But if you still have a v-for with a list the best solution is still to filter the list then give the filtered list to your v-for. Then in your JSX component you only care about rendering the component and never return null.

Yes that is weird that transition-group is trying to transition something that doesn't exist but it can be easily avoided. Maybe somebody who knows more about that can look at it.

what is c$1.elm.getBoundingClientRect is not a function?
Did you fix?

Any update?

i have the same issue

I am having the same issue but with v-show on 2.6.10

@selfagency This issue is almost 1.5 years old and using v-show was established as a workaround.

So if you have the same issue now, 1.5 years later, but with v-show, it might be a good idea to

  1. Open a new issue
  2. Provide runnable code that demonstrates the problem.

Otherwise you will likely not get helpful feedback.

@LinusBorg I figured out my issue—

In my component, I was trying to alternate between two global components using v-show. My guess was that the subcomponent needed to render before trying to attach an event to it, and there was a race condition preventing it from doing so. So, I wrapped the global components in div tags and put the v-show on those, and then my problem was solved. Could this possibly also be resolved by using an async component?

Before (throws error)

<transition-group name="zoom" mode="out-in"> 
  <inline-svg v-show="modal" key="close" :src="close" width="25" height="25"></inline-svg>
  <inline-svg v-show="!modal" key="open" :src="open" width="25" height="25"></inline-svg>
</transition-group> 

After (no error)

<transition-group name="zoom" mode="out-in">
  <div v-show="modal" key="close">
    <inline-svg :src="close" width="25" height="25"></inline-svg>
  </div>
  <div v-show="!modal" key="open">
    <inline-svg :src="open" width="25" height="25"></inline-svg>
  </div>
</transition-group>

I hope this helps others.

PR which would fix this issue: #11128

Was this page helpful?
0 / 5 - 0 ratings

Related issues

loki0609 picture loki0609  ·  3Comments

guan6 picture guan6  ·  3Comments

hiendv picture hiendv  ·  3Comments

robertleeplummerjr picture robertleeplummerjr  ·  3Comments

seemsindie picture seemsindie  ·  3Comments