--- name: script-setup-macros description: Vue 3 script setup syntax and compiler macros for defining props, emits, models, and more --- # Script Setup & Macros ` ``` ## defineProps Declare component props with full TypeScript support. ```ts // Type-based declaration (recommended) const props = defineProps<{ title: string; count?: number; items: string[]; }>(); // With defaults (Vue 3.5+) const { title, count = 0 } = defineProps<{ title: string; count?: number; }>(); // With defaults (Vue 3.4 and below) const props = withDefaults( defineProps<{ title: string; items?: string[]; }>(), { items: () => [], // Use factory for arrays/objects }, ); ``` ## defineEmits Declare emitted events with typed payloads. ```ts // Named tuple syntax (recommended) const emit = defineEmits<{ update: [value: string]; change: [id: number, name: string]; close: []; }>(); emit('update', 'new value'); emit('change', 1, 'name'); emit('close'); ``` ## defineModel Two-way binding prop consumed via `v-model`. Available in Vue 3.4+. ```ts // Basic usage - creates "modelValue" prop const model = defineModel(); model.value = 'hello'; // Emits "update:modelValue" // Named model - consumed via v-model:name const count = defineModel('count', { default: 0 }); // With modifiers const [value, modifiers] = defineModel(); if (modifiers.trim) { // Handle trim modifier } // With transformers const [value, modifiers] = defineModel({ get(val) { return val?.toLowerCase(); }, set(val) { return modifiers.trim ? val?.trim() : val; }, }); ``` Parent usage: ```vue ``` ## defineExpose Explicitly expose properties to parent via template refs. Components are closed by default. ```ts import { ref } from 'vue'; const count = ref(0); const reset = () => { count.value = 0; }; defineExpose({ count, reset, }); ``` Parent access: ```ts const childRef = ref<{ count: number; reset: () => void }>(); childRef.value?.reset(); ``` ## defineOptions Declare component options without a separate ` ``` Multiple generics with constraints: ```vue ``` ## Local Custom Directives Use `vNameOfDirective` naming convention. ```ts const vFocus = { mounted: (el: HTMLElement) => el.focus(), }; // Or import and rename import { myDirective as vMyDirective } from './directives'; ``` ```vue ``` ## Top-level await Use `await` directly in ` ```