Skip to content
← All questions
Advanced

What are all the compiler macros in Vue?

Composition APITypeScript

Compiler macros are special functions that only work inside <script setup>. They're processed at compile time and don't need to be imported. Vue 3.5 has six of them.

defineProps

Declares the props the component accepts. Returns a reactive object.

vue
<script setup lang="ts">
const props = defineProps<{
  title: string
  count?: number
}>()

// With defaults
const props = withDefaults(defineProps<{
  title: string
  items?: string[]
}>(), {
  items: () => []
})
</script>

defineEmits

Declares the events the component can emit. Returns a typed emit function.

vue
<script setup lang="ts">
const emit = defineEmits<{
  submit: [data: FormData]
  cancel: []
}>()

emit('submit', formData)
</script>

defineModel (Vue 3.4+)

Creates a two-way binding for v-model. Returns a ref that reads from the prop and emits on write.

vue
<script setup lang="ts">
const name = defineModel<string>('name', { required: true })
const checked = defineModel<boolean>({ default: false })

// With custom modifiers
const [text, modifiers] = defineModel<string>({
  set(value) {
    return modifiers.trim ? value.trim() : value
  }
})
</script>

defineExpose

Controls what the component exposes to parent template refs. Without it, <script setup> components expose nothing.

vue
<script setup>
import { ref } from 'vue'

const count = ref(0)
function reset() { count.value = 0 }

defineExpose({ count, reset })
</script>

defineOptions (Vue 3.3+)

Sets component options that don't have a macro equivalent, like name and inheritAttrs.

vue
<script setup>
defineOptions({
  name: 'MyComponent',
  inheritAttrs: false
})
</script>

Before 3.3, you needed a separate <script> block for these.

defineSlots (Vue 3.3+)

Declares slot types for TypeScript. Returns the slots object (same as useSlots()).

vue
<script setup lang="ts">
const slots = defineSlots<{
  default: (props: { item: User }) => any
  header: (props: { title: string }) => any
  empty: () => any
}>()
</script>

This doesn't change runtime behavior. It only provides type checking for slot props in the template and for consumers using the component.

Summary table

MacroSincePurposeReturns
defineProps3.0Declare propsReactive props object
defineEmits3.0Declare eventsTyped emit function
defineModel3.4Two-way v-model bindingWritable ref
defineExpose3.0Control public API for refsvoid
defineOptions3.3Set name, inheritAttrs, etc.void
defineSlots3.3Type slot propsSlots object

Rules that apply to all macros

  • They only work inside <script setup>, not in regular <script> or .ts files.
  • Don't import them. The compiler removes them at build time.
  • They must be called at the top level, not inside functions or conditionals.
  • defineProps and defineEmits can't be used in the same component as their Options API equivalents (props, emits).

See also: What is script setup? · What is defineExpose and when is it needed?

References

Released under the MIT License.