At the Communication Station, signals don't go in only one direction! When Mars receives data, it sends confirmation back to Earth. In Vue, a child communicates with its parent through custom events - signals emitted up the component tree.
In
<script setup> we declare emitted events via defineEmits:1<!-- SignalButton.vue (child) -->
2<script setup>
3const emit = defineEmits(['signal-sent', 'error'])
4
5const sendSignal = () => {
6 emit('signal-sent', { message: 'OK', time: Date.now() })
7}
8
9const reportError = (code) => {
10 emit('error', code)
11}
12</script>
13
14<template>
15 <button @click="sendSignal">Send</button>
16</template>The parent listens for events via
@event-name or v-on:event-name:1<!-- Parent.vue -->
2<template>
3 <SignalButton
4 @signal-sent="handleSignal"
5 @error="handleError"
6 />
7</template>
8
9<script setup>
10const handleSignal = (data) => {
11 console.log('Signal received:', data.message)
12}
13
14const handleError = (code) => {
15 console.error('Error:', code)
16}
17</script>Emit can pass any data as payload:
1<script setup>
2const emit = defineEmits(['submit'])
3
4const onSubmit = () => {
5 // Single argument
6 emit('submit', 'data')
7
8 // Multiple arguments
9 emit('submit', name, email, role)
10
11 // Object
12 emit('submit', { name, email, role })
13}
14</script>The object syntax of
defineEmits allows payload validation:1<script setup>
2const emit = defineEmits({
3 // No validation
4 click: null,
5
6 // With validation
7 submit: (payload) => {
8 if (!payload.email) return false
9 if (!payload.email.includes('@')) return false
10 return true
11 }
12})
13</script>