JAVASCRIPT
Vue 3 Deep Component Communication with Provide/Inject
Share configuration or reactive state deep down your component tree in Vue 3 using the `provide` and `inject` API, avoiding excessive prop drilling.
// ParentComponent.vue
<template>
<div>
<h2>Parent Component</h2>
<p>Theme from parent: {{ theme }}</p>
<button @click="toggleTheme">Toggle Parent Theme</button>
<GrandchildComponent />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import GrandchildComponent from './GrandchildComponent.vue';
const theme = ref('light');
const toggleTheme = () => {
theme.value = theme.value === 'light' ? 'dark' : 'light';
};
// Provide the reactive theme and a method to change it
provide('app-theme', {
theme, // A reactive ref
toggleTheme, // A method
});
</script>
// GrandchildComponent.vue (or any deeply nested component)
<template>
<div :style="{ backgroundColor: injectedTheme.theme.value === 'dark' ? '#333' : '#eee', color: injectedTheme.theme.value === 'dark' ? '#eee' : '#333', padding: '10px', margin: '10px' }">
<h3>Grandchild Component</h3>
<p>Injected Theme: {{ injectedTheme.theme.value }}</p>
<button @click="injectedTheme.toggleTheme">Toggle Injected Theme</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the provided values
const injectedTheme = inject('app-theme', {
theme: ref('light'), // Default value if not provided
toggleTheme: () => console.warn('Theme toggle function not provided!')
});
</script>
How it works: This snippet illustrates Vue 3's `provide` and `inject` API for dependency injection. The `ParentComponent` `provide`s a reactive `theme` and a `toggleTheme` method. Deeply nested components, like `GrandchildComponent`, can then `inject` these values without needing to pass them down through every intermediate prop, simplifying communication and code structure.