Skip to content

useVueValidDefineEmits (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueValidDefineEmits": "error"
}
}
}
}

Enforce valid usage of Vue’s defineEmits macro.

defineEmits declares the events that a component can send to its parent. Vue reads the call when it compiles the component, so the call must follow a few rules. This rule reports a defineEmits call in <script setup> when:

  • It declares the events with both a type and an argument. Vue accepts only one of the two, and fails to compile the component when both are present.
  • Its argument uses a variable, function, or class declared in the same <script setup> block. Vue evaluates the argument before the code in <script setup> runs, so these names do not exist yet. Imported names and names declared in a separate <script> block can be used.
  • It comes after another defineEmits call. Vue allows a single call per component, and fails to compile the component when there are more.
  • It has neither a type nor an argument, so it declares no events.

This rule only checks the <script setup> block. It does not read an emits option declared in a separate <script> block of the same file.

<script setup lang="ts">
const emit = defineEmits<(e: 'notify') => void>(['submit'])
</script>
code-block.vue:2:14 lint/nursery/useVueValidDefineEmits ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This defineEmits call declares events with both a type and an argument.

1 │ <script setup lang="ts">
> 2 │ const emit = defineEmits<(e: 'notify') => void>(['submit'])
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ Vue accepts only one of the two, and fails to compile the component when both are present.

ℹ Remove either the type between the angle brackets or the argument.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
const events = ['notify']
const emit = defineEmits(events)
</script>
code-block.vue:3:26 lint/nursery/useVueValidDefineEmits ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This defineEmits argument uses a name that is declared in the same <script setup> block.

1 │ <script setup>
2 │ const events = ['notify']
> 3 │ const emit = defineEmits(events)
│ ^^^^^^
4 │ </script>
5 │

ℹ The name is declared here.

1 │ <script setup>
> 2 │ const events = ['notify']
│ ^^^^^^
3 │ const emit = defineEmits(events)
4 │ </script>

ℹ Vue evaluates the defineEmits argument before the code in <script setup> runs, so this name does not exist yet.

ℹ Write the value directly in the argument, import it from another file, or declare it in a separate <script> block.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
defineEmits(['notify'])
defineEmits(['submit'])
</script>
code-block.vue:3:1 lint/nursery/useVueValidDefineEmits ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineEmits is called more than once in this <script setup> block.

1 │ <script setup>
2 │ defineEmits(['notify'])
> 3 │ defineEmits(['submit'])
│ ^^^^^^^^^^^^^^^^^^^^^^^
4 │ </script>
5 │

ℹ The first call is here.

1 │ <script setup>
> 2 │ defineEmits(['notify'])
│ ^^^^^^^^^^^^^^^^^^^^^^^
3 │ defineEmits(['submit'])
4 │ </script>

ℹ Vue allows a single defineEmits call per component, and fails to compile the component when there are more.

ℹ Declare all the events of the component in one call.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
const emit = defineEmits()
</script>
code-block.vue:2:14 lint/nursery/useVueValidDefineEmits ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This defineEmits call does not declare any events.

1 │ <script setup>
> 2 │ const emit = defineEmits()
│ ^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ Vue does not know which events the component sends, so it treats listeners for them as plain attributes and passes them to the root element of the component.

ℹ Declare the events with an array of names, an object, or a type.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
import { events } from './events'
const emit = defineEmits(events)
</script>
<script setup lang="ts">
const emit = defineEmits<(e: 'notify') => void>()
</script>