The Problem
<TransitionGroup> requires every child to have a unique key. When keys are duplicated, Vue cannot track which items are entering, leaving, or moving, resulting in broken animations and console warnings.
Symptoms
- Console warning: "Duplicate keys found during transition"
- List items animate incorrectly (wrong item fades out)
- Stagger animations apply to wrong elements
- Items jump to wrong positions during reorder
Real Error Message
[Vue warn]: <TransitionGroup> children must be keyed.
Found duplicate key: "item-3"Common Causes
Cause 1: Using Index as Key
<TransitionGroup name="list" tag="ul">
<li v-for="(item, index) in items" :key="index"> <!-- BAD -->
{{ item.name }}
</li>
</TransitionGroup>Cause 2: Non-Unique IDs from Backend
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item.category"> <!-- Multiple items share category -->
{{ item.name }}
</li>
</TransitionGroup>How to Fix It
Fix 1: Use Unique IDs
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</TransitionGroup>Fix 2: Generate Unique Keys for Items Without IDs
<TransitionGroup name="list" tag="ul">
<li v-for="(item, index) in items" :key="`item-${item.name}-${index}`">
{{ item.name }}
</li>
</TransitionGroup>Fix 3: Deduplicate Before Rendering
const uniqueItems = computed(() => {
const seen = new Set();
return items.value.filter(item => {
if (seen.has(item.id)) return false;
seen.add(item.id);
return true;
});
});<TransitionGroup name="list" tag="ul">
<li v-for="item in uniqueItems" :key="item.id">
{{ item.name }}
</li>
</TransitionGroup>CSS for Smooth Transitions
.list-enter-active,
.list-leave-active {
transition: all 0.3s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateY(20px);
}
.list-move {
transition: transform 0.3s ease;
}