generic3892372
generic3892372

Reputation: 206

vue.js how to address warning "<transition> can only be used on a single element. "

I'm using a transition for a component I created that repeats multiple times on the rendered view:

<slide-y-down-transition>
    <div
      v-for="comment in comment.comments"
      :key="comment.id"
      v-show="displayComments"
    >
      <CommentCard
      />
    </div>
</slide-y-down-transition>

But when I test the view it provides a console warning:

[Vue warn]: <transition> can only be used on a single element. Use <transition-group> for lists.

So I researched it and found that the documentation recommends using 'group'. This is a third party package called "vue2-transitions" with a group prop, so I tried out:

<slide-y-down-transition group>
    <div
      v-for="comment in comment.comments"
      :key="comment.id"
      v-show="displayComments"
    >
      <CommentCard
      />
    </div>
</slide-y-down-transition>

This eliminated the warning, but resulted in unexpected behavior; instead of pushing the rest of the view's content down as the section is expanded or contracted, it seems to do a 'v-show' without first pushing down the rest of the view's content. As a result, the view's bottom content is overlayed with the newly-revealed CommentCard. It looks atrocious:

enter image description here

I don't want to alter the 3rd party package ("vue2-transitions") if I can help it. I'm sure if an original creator of the package can comment, it would clear things up.

So I'm now just investigating how I can continue to use the normal transition without the 'group'? It works fine, but I'm concerned about the Vue warning.

My Question: What causes this Vue warning, and is there any way to address it without resorting to using a 'group' transition?

Other (Possibly) Important Info: The CommentCard is recursive.

In other words, the comment list can contain multiple CommentCards as shown, and each of those CommentCards can contain its own list of CommentCards. The idea is for the transition to display (or NOT display) those child lists of comments.

Upvotes: 2

Views: 5803

Answers (2)

Dan Knights
Dan Knights

Reputation: 8368

<transition> is for:

  • Individual nodes
  • Multiple nodes where only 1 is rendered at a time

For simultaneously rendered elements you need to use <transition-group> and give keys to each element.

You can read more here.

Upvotes: 2

generic3892372
generic3892372

Reputation: 206

To eliminate this error, I ended up with the following code in my CommentCard component:

<template>
  <slide-y-down-transition>
     // MORE CODE HERE
          <slide-y-down-transition>
            <div v-show="displayComments">
              <div v-for="comment in comment.comments" :key="comment.id">
                <CommentCard
                  :comment="comment"
                />
              </div>
            </div>
          </slide-y-down-transition>

  </slide-y-down-transition>
</template>

<script>
export default {
  name: "CommentCard",

  // MORE CODE HERE
}
</script>
<style scoped>
</style>

The key for me was the recursive behavior. To keep the vertical collapse-expand transition working, I needed to add the transition to each individual CommentCard's overall template, and then within each CommentCard, place a transition on each one's individual 'child list' of comments.

Works perfect with no Vue warnings now.

What I learned is that the group option is necessary on list items to handle each transition separately within a group context.

However.... if you wrap an overall list item in a single div tag, you can appropriately move the v-show out of the list and into that single enclosing div tag like so:

 <div v-show="displayComments">

That way, Vue.js will consider the v-show to be for 'one' element and it will treat the transition as collapsing or expanding that entire div, which includes all the sub elements.

Since I wanted the whole child group to be expanded or contracted, that works fine in my case; however, if you do need finer-grained control over visibility or transition of individual child elements, you'll need to look further than what I did.

Upvotes: 1

Related Questions