Child -> Parent Communication Vue3: emit events with data

December 3rd, 2022

The child emits an event, parent catches the event (only the direct parent can listen to that event)

If you need communication between siblings, or other deeply nested components, then u need a global store (pinia) or external event bus (mitt())

Basic emit event in Child and listen for emitted event in Parent component

1// Child: Form.vue
2 
3<script setup>
4const emit = defineEmits(['submitAnswer'])
5 
6function submitAnswer(){
7 // ...
8 emit('submitAnswer')
9}
10</script>
11 
12// Direct Parent
13 
14<Form @submit-answer="sayThankYou" />
15 
16<script setup>
17 function sayThankYou(){
18 //
19 }
20</script>

Send data with emitting event in Vue3

Send data with emitting event and when event emitted, set data back to default (or 0 in our case)

1// Child.vue
2<script setup>
3 const count = ref(0)
4</script>
5 
6<template>
7 <input type="number" v-model="count" />
8 <button @click="$emit('addToCart', count), (count = 0)">Add to Cart</button>
9// ...
10</template

Listen for emitted event in direct parent, and accept data. When @add-to-cart event is triggered, run method addToCart which accepts $event (our emitted data from Child component) and product

1// Parent.vue
2<ProductCard
3 v-for="product in products"
4 :key="product.id"
5 :product="product"
6 @add-to-cart="addToCart($event, product)" />
7 
8// ...
9 
10<script setup>
11 function addToCard(count, product){
12 // ...
13 }

Event validation

1// Child: Form.vue
2 
3<script setup>
4defineEmits({
5 submitAnswer: ({ data }) => {
6 if ( data ) {
7 return true
8 } else {
9 console.warn('Invalid submit!')
10 return false
11 }
12 
13 }
14})
15 
16function submitAnswer(data){
17 // ...
18 emit('submitAnswer', { data })
19}
20</script>
21 
22// Direct Parent
23 
24<Form @submit-answer="sayThankYou" />
25 
26<script setup>
27 function sayThankYou(){
28 //
29 }
30</script>

v-model as prop, white emit update modelValue, send data

1<CustomInput v-model="searchText" />
2 
3// CustomInput.vue Child
4<script setup>
5 defineProps(['modelValue'])
6</script>
7 
8<template>
9 <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"
10</template>

v-model arguments

1<MyComponent v-model:title="bookTitle" />
2 
3// MyComponent.vue -- Child
4 
5<script setup>
6defineProps(['title'])
7defineEmits(['update:title')
8</script>
9 
10<template>
11 <input type="text" value="title" @input="$emit('update:title', $event.target.value)" />
12</template>

Related Posts