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 isspan).key: Required on each child for tracking.- Use CSS classes like
v-enter-from,v-enter-active,v-leave-tofor 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
keyon each child, causing Vue to fail tracking elements and animations. - Using
transitioninstead oftransition-groupfor lists, which only animates single elements. - Forgetting to set the
tagattribute 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-groupfor animating lists. - Always add a unique
keyto each child element. - Set
tagto control the wrapper element type. - Define CSS classes with the
nameprefix 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.