$emit method for custom events
A component can emit custom events using the built-in $emit method. In templates, use $emit directly in expressions like @click="$emit('someEvent')". In Options API, $emit is available as this.$emit() on the component instance. In Composition API with <script setup>, $emit is not directly accessible in the script section, but defineEmits() returns an equivalent function that can be used instead.
Listening to component events with v-on
Parent components listen to custom events emitted by child components using v-on directive. Event names are automatically transformed from camelCase to kebab-case, so a camelCase event like 'someEvent' can be listened to using @some-event="callback". The .once modifier is supported on component event listeners.
Component events do not bubble
Component emitted events do not bubble, unlike native DOM events. You can only listen to events emitted by a direct child component. To communicate between sibling or deeply nested components, use an external event bus or a global state management solution.
Passing arguments with emitted events
Extra arguments can be passed to $emit after the event name to provide values to the listener. For example, $emit('increaseBy', 1) will pass 1 as an argument to the listener. In the parent, the inline arrow function listener can access the argument as (n) => count += n, or a method handler receives the value as its first parameter.
defineEmits macro in Composition API
In Composition API with <script setup>, use the defineEmits() macro to declare emitted events. It accepts an array of event names like defineEmits(['inFocus', 'submit']) and returns an emit function that can be used in the script section. The defineEmits() macro cannot be used inside a function and must be placed directly within <script setup>.
emits option in Options API and setup function
In Options API, declare emitted events using the emits option: emits: ['inFocus', 'submit']. When using an explicit setup function, declare events with the emits option and access the emit function from the setup context via ctx.emit or by destructuring { emit } from the context.
Object syntax for emits with validation
The emits option and defineEmits() macro support an object syntax for validating emitted events. In the object syntax, each event is assigned a validation function that receives the arguments passed to emit and returns true if valid or false if invalid. For example: emit: ({ email, password }) => { return email && password ? true : false }
TypeScript type annotations for emits
In Composition API with TypeScript and <script setup>, emitted events can be declared using pure type annotations: const emit = defineEmits<{ (e: 'change', id: number): void, (e: 'update', value: string): void }>(). This allows static type checking of event names and argument types.
Benefits of declaring emitted events
Declaring all emitted events in a component is recommended for better documentation of how a component should work. It also allows Vue to exclude known listeners from fallthrough attributes, avoiding edge cases caused by DOM events manually dispatched by third-party code.
Native events in emits option override native behavior
If a native event like 'click' is defined in the emits option, the listener will only listen to component-emitted click events and will no longer respond to native click events.
$emit method for custom events
Child components emit custom events using the built-in $emit method: @click="$emit('enlarge-text')". Parents listen to these events using v-on or @ syntax: @enlarge-text="postFontSize += 0.1". The event name is passed as a string to $emit.
Declaring emitted events with Options API emits option
Declare emitted events using the emits option in a component's default export: emits: ['enlarge-text']. This documents all events the component emits, optionally validates them, and prevents Vue from implicitly applying them as native listeners to the child component's root element.
Declaring emitted events with defineEmits macro
In <script setup>, use defineEmits to declare events: defineEmits(['enlarge-text']). defineEmits is a compile-time macro available only in <script setup> and returns an emit function equivalent to $emit. This allows emitting events in the <script setup> section where $emit is not directly accessible.
Accessing emit function in setup without script setup
When not using <script setup>, declare emitted events with the emits option and access the emit function through the setup context as the second argument: export default { emits: ['enlarge-text'], setup(props, ctx) { ctx.emit('enlarge-text') } }.
defineEmits runtime declaration example
```vue
<script setup lang="ts">
const emit = defineEmits(['change', 'update'])
</script>
```
This example shows the simplest form of emits declaration with just event names.
defineEmits options-based declaration example
```vue
<script setup lang="ts">
const emit = defineEmits({
change: (id: number) => {
// return `true` or `false` to indicate validation pass / fail
},
update: (value: string) => {
// return `true` or `false` to indicate validation pass / fail
}
})
</script>
```
This example shows options-based emits declaration where each event has a validator function that returns true or false for validation pass/fail.
defineEmits type-based declaration example
```vue
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
// 3.3+: alternative, more succinct syntax
const emit = defineEmits<{
change: [id: number]
update: [value: string]
}>()
</script>
```
This example shows type-based emits declaration. The type argument can use call signatures or, in 3.3+, a more succinct syntax with named tuples.
defineEmits type argument forms
The type argument for defineEmits can be one of two forms: (1) A callable function type written as a type literal with call signatures, used as the type of the returned emit function. (2) A type literal where keys are event names and values are array/tuple types representing the additional accepted parameters for each event. Named tuples allow explicit names for each argument.
Typing component emits with object syntax in Options API
Declare expected payload types for emitted events using the object syntax of the emits option. When using object syntax with function declarations, you can specify the payload type. All non-declared emitted events will throw a type error when called. Example: emits: { addBook(payload: { bookName: string }) { return payload.bookName.length > 0 } }
Example: Typing component emits with payload validation
import { defineComponent } from 'vue'
export default defineComponent({
emits: {
addBook(payload: { bookName: string }) {
// perform runtime validation
return payload.bookName.length > 0
}
},
methods: {
onSubmit() {
this.$emit('addBook', {
bookName: 123 // Type error!
})
this.$emit('non-declared-event') // Type error!
}
}
})