JAVASCRIPT
Vue 3 Component Communication: Props, Emits, and Slots
Master passing data with `defineProps`, emitting events with `defineEmits`, and rendering dynamic content using slots for robust Vue 3 component communication.
<!-- ParentComponent.vue -->
<template>
<div>
<h2>Parent Component</h2>
<ChildComponent
:message="parentMessage"
@child-event="handleChildEvent"
>
<!-- Default Slot Content -->
<p>This is content for the default slot from parent.</p>
<!-- Named Slot Content -->
<template #footer>
<p>This is content for the footer slot from parent.</p>
</template>
</ChildComponent>
<p>Message from child: {{ messageFromChild }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentMessage = ref('Hello from parent!');
const messageFromChild = ref('');
const handleChildEvent = (payload) => {
messageFromChild.value = `Child says: ${payload}`;
console.log('Child event received with payload:', payload);
};
</script>
<!-- ChildComponent.vue -->
<template>
<div style="border: 1px solid blue; padding: 10px; margin-top: 10px;">
<h3>Child Component</h3>
<p>Prop Message: {{ message }}</p>
<button @click="emitEvent">Emit Event to Parent</button>
<hr>
<h4>Default Slot:</h4>
<slot></slot>
<hr>
<h4>Named Slot 'footer':</h4>
<slot name="footer"></slot>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Define props
const props = defineProps({
message: String
});
// Define emits
const emits = defineEmits(['child-event']);
const emitEvent = () => {
emits('child-event', 'I am the child!');
};
</script>
How it works: This example showcases essential Vue 3 component communication using `script setup`. `defineProps` is used in `ChildComponent` to declare incoming properties like `message`. `defineEmits` declares custom events, allowing `ChildComponent` to send data back to its parent via `emits('child-event', payload)`. Slots provide a way to inject content from the parent into the child component's template, supporting both default and named slots for flexible content distribution.