feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: TransitionGroup Children Must Have Unique Keys
|
||||
impact: HIGH
|
||||
impactDescription: Missing or non-unique keys cause broken animations and Vue warnings
|
||||
type: gotcha
|
||||
tags: [vue3, transition-group, animation, key, v-for, list-animation]
|
||||
---
|
||||
|
||||
# TransitionGroup Children Must Have Unique Keys
|
||||
|
||||
**Impact: HIGH** - Unlike regular `<Transition>`, the `<TransitionGroup>` component **always requires** a unique `key` attribute on every child element. Without keys, Vue cannot track individual items, animations will break, and you'll see console warnings.
|
||||
|
||||
This is a fundamental difference from `<Transition>` which works on single elements. Since `<TransitionGroup>` animates lists of elements, Vue needs keys to track which items are entering, leaving, or moving.
|
||||
|
||||
## Task Checklist
|
||||
|
||||
- [ ] Ensure every direct child of `<TransitionGroup>` has a unique `key` attribute
|
||||
- [ ] Use stable identifiers (IDs) rather than array indices for keys
|
||||
- [ ] Do not use the same key for different items at different times
|
||||
- [ ] When using `v-for`, always include `:key` binding
|
||||
|
||||
**Incorrect - Missing keys:**
|
||||
```vue
|
||||
<template>
|
||||
<!-- WRONG: Missing keys causes broken animations -->
|
||||
<TransitionGroup name="list" tag="ul">
|
||||
<li v-for="item in items">
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
```
|
||||
|
||||
**Incorrect - Using index as key:**
|
||||
```vue
|
||||
<template>
|
||||
<!-- PROBLEMATIC: Index keys cause incorrect animations when list changes -->
|
||||
<TransitionGroup name="list" tag="ul">
|
||||
<li v-for="(item, index) in items" :key="index">
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
```
|
||||
|
||||
When using index as key:
|
||||
- If you remove item at index 2, what was index 3 becomes index 2
|
||||
- Vue thinks index 2 changed content rather than being removed
|
||||
- Animations fire on wrong elements
|
||||
|
||||
**Correct - Unique stable keys:**
|
||||
```vue
|
||||
<template>
|
||||
<!-- CORRECT: Unique ID keys for proper tracking -->
|
||||
<TransitionGroup name="list" tag="ul">
|
||||
<li v-for="item in items" :key="item.id">
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
```
|
||||
|
||||
**Correct - Keys on static children:**
|
||||
```vue
|
||||
<template>
|
||||
<!-- CORRECT: Even static children need keys in TransitionGroup -->
|
||||
<TransitionGroup name="fade" tag="div">
|
||||
<span v-if="showA" key="a">Content A</span>
|
||||
<span v-if="showB" key="b">Content B</span>
|
||||
<span v-if="showC" key="c">Content C</span>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Common Error Messages
|
||||
|
||||
Without keys, you'll see warnings like:
|
||||
```
|
||||
[Vue warn]: <TransitionGroup> children must be keyed.
|
||||
```
|
||||
|
||||
## With Draggable Libraries
|
||||
|
||||
When using `<TransitionGroup>` with libraries like `vue.draggable.next`, key issues can cause errors:
|
||||
|
||||
```javascript
|
||||
// Error you might see without proper keys
|
||||
TypeError: domElement is null
|
||||
```
|
||||
|
||||
Ensure all draggable items have unique keys:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<draggable v-model="items" item-key="id">
|
||||
<template #item="{ element }">
|
||||
<TransitionGroup name="list" tag="div">
|
||||
<div :key="element.id">{{ element.name }}</div>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
</draggable>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Reference
|
||||
- [Vue.js TransitionGroup](https://vuejs.org/guide/built-ins/transition-group.html)
|
||||
- [Vue.js List Rendering Keys](https://vuejs.org/guide/essentials/list.html#maintaining-state-with-key)
|
||||
Reference in New Issue
Block a user