0

I want to create a treeview component in vue with animations. My idea was to create the treeview recursively without any animations first and then add the TransitionsGroup tag around it.

So you pass a node and its childrens (an array of nodes and its childrens again) to the tree component and it creates the tree. The resulting tree is correct and its HTML will look as follows:

<div v-if.. :key="..">
  Root1
</div>

<div v-if.. :key="..">
  Child1.1
</div>

<div v-if.. :key="..">
  Child2.1
</div>

<div v-if.. :key="..">
  Child2.2
</div>

<div v-if.. :key="..">
  Child1.2
</div>

But if I add this component inside a TransitionGroup like this

<TransitionGroup tag="div" name="fade">
  <Tree :treeData="... /> 
</TransitionGroup>

I will get warning because the childrens of TransitionGroup must be keyed. So I provided one. But this will result in the following message:

Component inside <Transition> renders non-element root node that cannot be animated.

How can you make this work? I will also appreciate any other ideas which solves this problem.

I also created the example in Vue SFC Playground here: Vue SFC Playground (Comp1 is the tree component and in App.vue line 64 is the problem).

Euler314
  • 21
  • 1

1 Answers1

0

updated Vue SFC Playground

As your error hinted, you didn't have a valid root node, and this is because Comp1 actually had two root nodes: <div> and <template>. Not only that, but as the docs state:

<TransitionGroup> is a built-in component designed for animating the insertion, removal, and order change of elements or components that are rendered in a list.

Meaning <TransitionGroup> expects its root component to be a v-for list of multiple rendered elements. Therefore instead of wrapping the entire Comp1 component in a <TransitionGroup> you should just wrap the v-for list of child elements:

  <TransitionGroup name="fade">
    <template v-for="(child, index) in treeData.children" :key="child.node.name + index.toString()">
        <Comp1
            v-if="isExpanded"
            :treeData="child"
            :indent="indent"
            :depth="depth + 1"
        />  
    </template>
  </TransitionGroup>
yoduh
  • 7,074
  • 2
  • 11
  • 21
  • 1
    Thank you! I do have one more question. If I click on the Child1.1 in then Child1.2 is jumping immediately to its final position whereas if you click on the toggle button at the top of the example Child1.2 is transitioning smoothly to its final position. Is it possible to make it work like described in the first case? – Euler314 Sep 04 '22 at 23:33