JAVASCRIPT
Deep Component Communication with Vue 3 provide/inject
Pass data efficiently down the component tree in Vue 3 without prop drilling using `provide` and `inject` for flexible dependency injection.
// ParentComponent.vue
<template>
<div>
<h1>Parent Component</h1>
<p>Shared Message from Parent: {{ parentMessage }}</p>
<IntermediateComponent />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import IntermediateComponent from './IntermediateComponent.vue';
const parentMessage = ref('Hello from the Parent!');
const updateMessage = (newMessage) => {
parentMessage.value = newMessage;
};
provide('messageKey', parentMessage); // Provide reactive ref
provide('updateMessageKey', updateMessage); // Provide a function
</script>
// IntermediateComponent.vue
<template>
<div style="margin-left: 20px; border-left: 1px solid #ccc; padding-left: 10px;">
<h2>Intermediate Component</h2>
<ChildComponent />
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
// This component doesn't need to explicitly know about 'messageKey' or 'updateMessageKey'
// It just passes through the rendering to ChildComponent
</script>
// ChildComponent.vue
<template>
<div style="margin-left: 20px; border-left: 1px solid #aaa; padding-left: 10px;">
<h3>Child Component</h3>
<p>Injected Message: {{ message }}</p>
<input type="text" v-model="localMessage" />
<button @click="updateParentMessage">Update Parent Message</button>
</div>
</template>
<script setup>
import { ref, inject } from 'vue';
const message = inject('messageKey'); // Inject the reactive ref
const updateMessageFromParent = inject('updateMessageKey'); // Inject the function
const localMessage = ref('');
function updateParentMessage() {
if (localMessage.value) {
updateMessageFromParent(localMessage.value);
localMessage.value = '';
}
}
</script>
How it works: The `provide`/`inject` mechanism in Vue 3 allows for dependency injection, solving the 'prop drilling' problem where props need to be passed through many layers of components unnecessarily. A parent component uses `provide` to make a piece of data or a function available. Any descendant component, no matter how deep, can then use `inject` to access that provided value using the same key. This example shows providing a reactive ref and a function, allowing a deeply nested child component to both read and modify the parent's state without direct prop passing.