---
title: defineEmits Must Be Used at Top Level of script setup
impact: HIGH
impactDescription: Using defineEmits inside functions causes compilation errors - macros must be at module scope
type: gotcha
tags: [vue3, defineEmits, script-setup, macros, composition-api]
---
# defineEmits Must Be Used at Top Level of script setup
**Impact: HIGH** - The `defineEmits()` macro can only be used directly within `
```
**Incorrect - Inside a conditional:**
```vue
```
**Incorrect - Referencing local variables:**
```vue
```
## Correct Usage
**Correct - Top level declaration:**
```vue
```
**Correct - With TypeScript types:**
```vue
```
**Correct - Using constant arrays (compile-time constant):**
```vue
```
## Why This Restriction Exists
Vue's compiler processes `
```
```js
// composables/useFormEvents.js
export function useFormEvents(emit) {
function handleSubmit(data) {
emit('submit', data)
}
function handleCancel() {
emit('cancel')
}
return { handleSubmit, handleCancel }
}
```
## ESLint Rule
The `eslint-plugin-vue` provides the `vue/valid-define-emits` rule that catches these errors:
```js
// eslint.config.js
export default [
{
rules: {
'vue/valid-define-emits': 'error'
}
}
]
```
This rule reports:
- `defineEmits` used inside functions
- `defineEmits` referencing local variables
- Multiple `defineEmits` calls in the same component
- `defineEmits` used outside `