0
0
VueHow-ToBeginner · 4 min read

How to Use Transition-Group in Vue for List Animations

Use Vue's transition-group component to animate multiple elements in a list by wrapping them inside it and applying CSS transition classes. Each child element must have a unique key for Vue to track and animate them properly.
📐

Syntax

The transition-group component wraps multiple elements to animate their entering, leaving, and moving states. It requires each child to have a unique key. You can specify the HTML tag it renders with the tag attribute, and use CSS classes or JavaScript hooks for animations.

  • <transition-group>: Wraps list items to animate.
  • tag: Optional, sets the wrapper element (default is span).
  • key: Required on each child for tracking.
  • Use CSS classes like v-enter-from, v-enter-active, v-leave-to for styling transitions.
vue
<transition-group name="fade" tag="ul">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</transition-group>
💻

Example

This example shows a list of items that fade in and out when added or removed. The transition-group wraps the list, and CSS handles the fade animation.

vue
<template>
  <div>
    <button @click="addItem">Add Item</button>
    <transition-group name="fade" tag="ul">
      <li v-for="item in items" :key="item.id">{{ item.text }}</li>
    </transition-group>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, text: 'Learn Vue' },
  { id: 2, text: 'Use transition-group' }
])

let nextId = 3

function addItem() {
  items.value.push({ id: nextId++, text: `New item ${nextId - 1}` })
}
</script>

<style scoped>
.fade-enter-from, .fade-leave-to {
  opacity: 0;
  transform: translateY(20px);
}
.fade-enter-active, .fade-leave-active {
  transition: all 0.3s ease;
}
</style>
Output
A button labeled 'Add Item' and a vertical list of items. When clicking the button, a new list item fades in smoothly below the existing items.
⚠️

Common Pitfalls

Common mistakes include:

  • Not providing a unique key on each child, causing Vue to fail tracking elements and animations.
  • Using transition instead of transition-group for lists, which only animates single elements.
  • Forgetting to set the tag attribute when wrapping block elements, leading to invalid HTML.
vue
<!-- Wrong: missing key -->
<transition-group name="fade" tag="ul">
  <li v-for="item in items">{{ item.text }}</li>
</transition-group>

<!-- Right: with unique key -->
<transition-group name="fade" tag="ul">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</transition-group>
📊

Quick Reference

  • Use transition-group for animating lists.
  • Always add a unique key to each child element.
  • Set tag to control the wrapper element type.
  • Define CSS classes with the name prefix for enter/leave animations.
  • Supports JavaScript hooks for advanced animations.

Key Takeaways

Wrap list items in transition-group to animate multiple elements together.
Always provide a unique key on each child for proper tracking and animation.
Use the tag attribute to specify the wrapper element type for valid HTML.
Define CSS classes with the name prefix to style enter and leave transitions.
Avoid using transition for lists; use transition-group instead.