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>
3.4 KiB
3.4 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | ||||
|---|---|---|---|---|---|---|---|---|
| VNodes Must Be Unique in Render Functions | HIGH | Reusing vnode references causes rendering bugs and unexpected behavior | gotcha |
|
VNodes Must Be Unique in Render Functions
Impact: HIGH - Reusing the same vnode reference multiple times in a render function tree causes rendering bugs, where only one instance appears or updates behave unexpectedly.
Every vnode in a component's render tree must be unique. You cannot use the same vnode object multiple times. If you need to render the same element multiple times, create each vnode separately using a factory function or by calling h() in a loop.
Task Checklist
- Never store a vnode in a variable and use it multiple times in the same tree
- Use a factory function or
.map()to create multiple similar vnodes - Each
h()call creates a new vnode, so call it for each instance needed - Be especially careful when extracting vnode creation into helper functions
Incorrect:
import { h } from 'vue'
export default {
setup() {
return () => {
// WRONG: Same vnode reference used twice
const p = h('p', 'Hello')
return h('div', [p, p]) // Bug! Duplicate vnode reference
}
}
}
import { h } from 'vue'
export default {
setup() {
return () => {
// WRONG: Reusing vnode in different parts of tree
const icon = h('span', { class: 'icon' }, '★')
return h('div', [
h('button', [icon, ' Save']), // Uses icon
h('button', [icon, ' Delete']) // Reuses same icon - Bug!
])
}
}
}
Correct:
import { h } from 'vue'
export default {
setup() {
return () => {
// CORRECT: Create new vnode for each use
return h('div', [
h('p', 'Hello'),
h('p', 'Hello')
])
}
}
}
import { h } from 'vue'
export default {
setup() {
return () => {
// CORRECT: Factory function creates new vnode each time
const createIcon = () => h('span', { class: 'icon' }, '★')
return h('div', [
h('button', [createIcon(), ' Save']),
h('button', [createIcon(), ' Delete'])
])
}
}
}
import { h } from 'vue'
export default {
setup() {
return () => {
// CORRECT: Using map to create multiple vnodes
return h('div',
Array.from({ length: 20 }).map(() => h('p', 'Hello'))
)
}
}
}
import { h } from 'vue'
export default {
setup() {
const items = ['Apple', 'Banana', 'Cherry']
return () => h('ul',
// CORRECT: Each iteration creates a new vnode
items.map((item, index) =>
h('li', { key: index }, item)
)
)
}
}
Why VNodes Must Be Unique
VNodes are lightweight JavaScript objects that Vue's virtual DOM algorithm uses for diffing and patching. When the same vnode reference appears multiple times:
- Vue cannot differentiate between the instances
- The diffing algorithm produces incorrect results
- Only one instance may render, or updates may corrupt the DOM
Each vnode maintains its own identity and position in the tree, which is essential for:
- Correct DOM patching during updates
- Proper lifecycle hook execution
- Accurate key-based reconciliation in lists