JAVASCRIPT
Vue 3 Component Communication: Props and Emits
Understand how to pass data down with `defineProps` and emit events up with `defineEmits` for effective communication between parent and child components in Vue 3.
<!-- ParentComponent.vue -->
<template>
<div>
<h1>Parent Component</h1>
<p>Message from Child: {{ childMessage }}</p>
<p>Parent Counter: {{ parentCounter }}</p>
<ChildComponent
:title="parentTitle"
:initial-count="parentCounter"
@send-message="handleChildMessage"
@increment-parent-count="incrementParentCount"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentTitle = ref('Data for Child');
const parentCounter = ref(10);
const childMessage = ref('');
const handleChildMessage = (message) => {
childMessage.value = message;
console.log('Received message from child:', message);
};
const incrementParentCount = (value) => {
parentCounter.value += value;
console.log('Parent counter incremented by child:', value);
};
</script>
<!-- ChildComponent.vue -->
<template>
<div class="child-container">
<h2>Child Component</h2>
<p>Prop Title: {{ title }}</p>
<p>Initial Count (Prop): {{ initialCount }}</p>
<button @click="sendMessageToParent">Send Message to Parent</button>
<button @click="emitIncrementEvent">Increment Parent Counter by 2</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Define props for receiving data from parent
const props = defineProps({
title: {
type: String,
required: true
},
initialCount: {
type: Number,
default: 0
}
});
// Define emits for sending events to parent
const emit = defineEmits(['send-message', 'increment-parent-count']);
const sendMessageToParent = () => {
emit('send-message', 'Hello from Child Component!');
};
const emitIncrementEvent = () => {
emit('increment-parent-count', 2); // Pass a value with the event
};
</script>
<style scoped>
.child-container {
border: 1px solid #ccc;
padding: 15px;
margin-top: 20px;
background-color: #f9f9f9;
}
</style>
How it works: In Vue 3, `defineProps` and `defineEmits` are compilers macros used within `<script setup>` for robust component communication. `defineProps` declares the props a component expects to receive from its parent, ensuring type validation and providing default values. Data flows downwards via props (one-way data flow). `defineEmits` declares the custom events a component can emit to its parent, allowing the child to communicate upwards. When an event is emitted, the parent component can listen for it using `v-on:` (or `@`) and react with a handler function. This parent-child communication pattern is fundamental for building modular and reusable Vue applications.