> vue3-component-decomposition
Decompose large Vue 3 components into focused SFCs and composables with explicit contracts, simple templates, and SSR-safe side effects.
curl "https://skillshub.wtf/noartem/skills/vue3-component-decomposition?format=md"Vue 3 Component Decomposition
Break large Vue 3 components into smaller, testable units without losing readability.
When to Use
- Component is handling multiple concerns (UI rendering, fetching, form logic, filtering, side effects)
setup()or<script setup>grows hard to scan- Template contains complex expressions or repeated blocks
- Changes in one feature frequently break unrelated behavior
Decomposition Workflow
- Map responsibilities before moving code:
view(markup/presentational)state(refs/reactive/computed)effects(watch/watchEffect/lifecycle)io(API calls)
- Extract presentational subcomponents first.
- Define explicit interfaces between parent and child (
props,emits,slots). - Extract reusable stateful logic into composables.
- Keep the parent as orchestrator of data flow and feature composition.
Component Best Practices
- Use one component per file and multi-word component names.
- Keep template expressions simple; move complex expressions to computed values.
- Use
:keywithv-forand do not combinev-ifwithv-foron the same element. - Use typed, explicit prop contracts and typed emits.
- Prefer
slotsfor variable UI regions over boolean prop explosion. - Keep child components focused on one UI concern.
Composable Best Practices
- Name composables with
useprefix (useOrdersTable,useUserFilters). - Return a plain object of refs/computed/methods so destructuring preserves reactivity.
- Accept reactive inputs (value/ref/getter) and normalize with
toValue(). - If logic depends on reactive inputs, call
toValue()inwatchEffect()(or watch refs/getters directly). - Perform DOM side effects in
onMounted()and always clean up inonUnmounted(). - Avoid hidden global mutable state unless intentionally building shared state.
Suggested Structure
src/
components/
feature/
OrdersPage.vue # orchestrator
OrdersToolbar.vue # presentational controls
OrdersTable.vue # table rendering
OrdersTableRow.vue # row rendering
composables/
useOrdersQuery.ts # fetch/pagination/sort
useOrdersFilters.ts # filter state and derived query
useOrdersSelection.ts # row selection logic
Guardrails
- Do not extract tiny wrappers with no independent value.
- Do not create "god composables"; split by business capability.
- Do not pass entire parent state into children; pass only required props.
- Do not mix business logic into presentational components.
PR Checklist
- Parent component reads as feature orchestration, not implementation dump.
- Children have clear APIs and can be reasoned about in isolation.
- Composables have focused responsibilities and predictable return shapes.
- Side effects are cleaned up and SSR-safe.
- Template complexity is reduced and tests can target smaller units.
References
- Vue docs: Composables - https://vuejs.org/guide/reusability/composables.html
- Vue style guide (outdated but still useful):
> related_skills --same-repo
> shadcn-vue
shadcn-vue for Vue/Nuxt with Reka UI components and Tailwind. Use for accessible UI, Auto Form, data tables, charts, dark mode, MCP server setup, or encountering component imports, Reka UI errors.
> laravel-transactions-and-consistency
Wrap multi-write operations in transactions; use dispatchAfterCommit and idempotency patterns to ensure consistency
> laravel-template-method-and-plugins
Stabilize workflows with Template Method or Strategy; extend by adding new classes instead of editing core logic
> laravel-task-scheduling
Schedule tasks with safety; use withoutOverlapping, onOneServer, and visibility settings for reliable cron execution