JAVASCRIPT
Passing Data Between Vue 3 Components with props and emits
Master inter-component communication in Vue 3 by passing data down using `props` and emitting custom events up using `emits` for modular and interactive UIs.
// ParentComponent.vue
<template>
<div>
<h1>Parent Component</h1>
<p>Message from Child: {{ childMessage }}</p>
<ChildComponent
:initial-count="parentCount"
:user-name="parentUserName"
@child-event="handleChildEvent"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentCount = ref(10);
const parentUserName = ref('Vue Dev');
const childMessage = ref('');
function handleChildEvent(message) {
childMessage.value = message;
console.log('Received from child:', message);
}
</script>
// ChildComponent.vue
<template>
<div style="border: 1px solid blue; padding: 10px; margin-top: 10px;">
<h3>Child Component</h3>
<p>Initial Count (prop): {{ initialCount }}</p>
<p>User Name (prop): {{ userName }}</p>
<button @click="emitEvent">Emit Event to Parent</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Define props with validation
const props = defineProps({
initialCount: {
type: Number,
required: true,
default: 0
},
userName: {
type: String,
validator: (value) => value.length > 2
}
});
// Define custom events that this component can emit
const emit = defineEmits(['child-event']);
function emitEvent() {
emit('child-event', 'Hello from Child!');
}
</script>
How it works: This example illustrates the fundamental pattern for parent-child component communication in Vue 3. Data flows downwards from a parent to a child using `props`, defined with `defineProps` in the child for type validation and default values. Information flows upwards from a child to a parent using custom events, defined with `defineEmits` in the child and triggered with `emit()`. The parent listens for these events using `v-on` (or `@`) and handles them with a method.