# Vue Components
Patterns for Vue 3 components using Composition API with `
```
### With Options
```vue
```
**⚠️ Warning:** When using `default` without parent providing a value, parent and child can de-sync (parent `undefined`, child has default). Always provide matching defaults in parent or make prop required.
**Prevent double-emit with `required: true`:**
```ts
// ❌ Without required - emits twice (undefined then value)
const model = defineModel()
// ✅ With required - single emit
const model = defineModel({ required: true })
```
Use `required: true` when the model should always have a value to avoid the double-emit issue during initialization.
### Multiple Models
Default assumes `modelValue` prop. For multiple bindings, use explicit names:
```vue
```
[v-model modifiers docs](https://vuejs.org/guide/components/v-model#handling-v-model-modifiers)
## Reusable Templates
For typed, scoped template snippets within a component:
```vue
{{ item.name }}
```
## Template Refs (Vue 3.5+)
Use `useTemplateRef()` for type-safe template references with IDE support:
```vue
```
**Benefits over `ref()`:**
- Type-safe with generics
- Better IDE autocomplete and refactoring
- Explicit ref name as string literal
**Dynamic refs:**
```vue
{{ item }}
```
**Component refs with generics:**
For generic components, use `ComponentExposed` from `vue-component-type-helpers`:
```ts
import type { ComponentExposed } from 'vue-component-type-helpers'
import MyGenericComponent from './MyGenericComponent.vue'
// Get exposed methods/properties with correct generic types
const compRef = useTemplateRef>('comp')
onMounted(() => {
compRef.value?.someExposedMethod() // Typed!
})
```
Install: `pnpm add -D vue-component-type-helpers`
## SSR Hydration (Vue 3.5+)
**Suppress hydration mismatches** for values that differ between server/client:
```vue
{{ new Date().toLocaleString() }}{{ timestamp }}............
```
**Generate SSR-stable IDs:**
```vue
```
## Deferred Teleport (Vue 3.5+)
Teleport to elements rendered later in the same cycle:
```vue
Deferred content
```
Without `defer`, teleport to `#late-div` would fail since it doesn't exist yet.
## Common Mistakes
**Using `const props =` with destructured values:**
```ts
// ❌ Wrong
const props = defineProps<{ count: number }>()
const { count } = props // Loses reactivity
```
**Forgetting TypeScript types:**
```ts
// ❌ Wrong
const emit = defineEmits(['update'])
// ✅ Correct
const emit = defineEmits<{ update: [id: number] }>()
```
**Components >300 lines:** Split into smaller components or extract logic to composables