--- description: Vue 3 Composition API conventions and best practices alwaysApply: false globs: **/*.vue --- # Vue.js Conventions & Best Practices ## Component Architecture ### Use Composition API with ` ``` ### Component Organization Order 1. **Imports** - External, then internal 2. **Props** - TypeScript-style validation 3. **Emits** - Explicitly defined 4. **State** (refs and reactive) 5. **Computed** - Derived values 6. **Watchers** - Side effects 7. **Methods** - Business logic 8. **Lifecycle hooks** - Ordered by execution 9. **Expose** - Public API (if needed) ## Props Best Practices ### Always Validate Props ```javascript defineProps({ title: { type: String, required: true, validator: (value) => value.length > 0 }, status: { type: String, default: 'pending', validator: (value) => ['pending', 'active', 'complete'].includes(value) } }) ``` ### Prop Naming - Use descriptive names: `isLoading` not `loading` - Boolean props: `is`, `has`, `can`, `should` - Avoid abbreviations: `projectData` not `projData` ## Reactive State ### When to Use ref vs reactive **Use `ref` for:** - Primitives (string, number, boolean) - Single values - When you need `.value` explicit access **Use `reactive` for:** - Objects with multiple properties - Complex nested data structures ## Event Handling ### Define Emits Explicitly ```javascript const emit = defineEmits(['update', 'delete', 'close']) const handleUpdate = () => { emit('update', { id: 1, name: 'Updated' }) } ``` ## Template Best Practices ### Keep Templates Clean ```vue ``` ## Performance Optimization ### Lazy Loading Components ```javascript // Router lazy loading const ProjectDetail = () => import('@/pages/ProjectDetail.vue') // Component lazy loading const HeavyChart = defineAsyncComponent(() => import('@/components/HeavyChart.vue') ) ``` ### Use `v-once` for Static Content ```vue

{{ staticTitle }}

``` ### Shallow Reactive for Large Objects ```javascript import { shallowRef } from 'vue' const projects = shallowRef([...largeArray]) ``` ## Common Pitfalls to Avoid ### ❌ Mutating Props Never mutate props directly - emit events instead ### ❌ Forgetting .value in script ```javascript const count = ref(0) if (count.value === 0) { } // ✅ Correct ``` ### ❌ Creating Objects in Template ```vue ``` ## Summary Checklist - ✅ Use Composition API with `