Vue 3 Component Patterns
Comprehensive guide for building Vue 3 components with the Composition API, focusing on reactive patterns, two-way binding, and modern best practices.
Core Patterns
| Topic | Description | Reference |
|---|---|---|
| Two-Way Binding | Modern defineModel API, v-model binding | bindings-definemodel |
| Props & Emits (Legacy) | defineProps, defineEmits, old v-model pattern | bindings-legacy-pattern |
| Reactive State | ref, reactive, computed, watchers | state-management |
| Lifecycle Hooks | onMounted, onUpdated, onUnmounted | lifecycle-hooks |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Component Composition | Splitting logic, code organization | best-practices-composition |
Quick Reference
✅ Use defineModel (Vue 3.4+)
For cleaner two-way data binding:
<script setup lang="ts">
// Single value binding
const modelValue = defineModel<number | null>();
// Multiple v-model bindings
const isOpen = defineModel<boolean>("isOpen");
const title = defineModel<string>("title");
</script>
<template>
<div>
<button @click="modelValue = modelValue ? null : 1">
Toggle: {{ modelValue }}
</button>
</div>
</template>
❌ Avoid: Old Pattern (Pre-Vue 3.4)
<script setup lang="ts">
const props = defineProps<{ modelValue: number | null }>();
const emit = defineEmits<{
(e: "update:modelValue", value: number | null): void;
}>();
// Then emit updates:
emit("update:modelValue", newValue);
</script>
When to Update Components
Refactor components using the old pattern when:
- Adding new two-way binding features
- Refactoring for code clarity
- Training new team members on current patterns
- Working in components shared across the codebase
Start with refactoring:
- High-reuse components (MediaPicker, FormFields, etc.)
- Components with multiple v-model bindings
- Components that will be documented as examples
Source: silvesterwali/nuxt-bare — distributed by TomeVault.