JAVASCRIPT
Deep Component Communication with provide and inject
Master Vue 3's `provide` and `inject` for efficient dependency injection, allowing data to be passed down deeply nested components without prop drilling.
import { defineComponent, provide, inject, ref } from 'vue';
// Parent Component
const ParentComponent = defineComponent({
setup() {
const theme = ref('dark');
const toggleTheme = () => {
theme.value = theme.value === 'dark' ? 'light' : 'dark';
};
// Provide a reactive value and a method
provide('appTheme', theme);
provide('toggleTheme', toggleTheme);
return { theme, toggleTheme };
},
template: `
<div :class="theme">
<h2>Parent Component (Theme: {{ theme }})</h2>
<button @click="toggleTheme">Toggle Theme</button>
<MiddleComponent />
</div>
`
});
// Middle Component (can be many levels deep)
const MiddleComponent = defineComponent({
template: `
<div style="margin-left: 20px; border: 1px solid gray; padding: 10px;">
<h3>Middle Component</h3>
<ChildComponent />
</div>
`
});
// Child Component
const ChildComponent = defineComponent({
setup() {
// Inject the provided values
const theme = inject('appTheme', 'default'); // 'default' is a fallback
const toggleTheme = inject('toggleTheme');
return { theme, toggleTheme };
},
template: `
<div style="margin-left: 20px;">
<h4>Child Component</h4>
<p>Current Theme (Injected): {{ theme }}</p>
<button v-if="toggleTheme" @click="toggleTheme">Toggle Theme from Child</button>
<p v-else>Toggle Theme function not provided.</p>
</div>
`
});
export default ParentComponent;
/*
<template>
<ParentComponent />
</template>
*/
How it works: This snippet demonstrates Vue 3's `provide` and `inject` features for dependency injection. The `ParentComponent` uses `provide` to make reactive data (`theme`) and a method (`toggleTheme`) available to its descendants. Deeply nested components, like `ChildComponent`, can then use `inject` to access these provided values without needing to pass them explicitly through props at each level, effectively solving prop drilling issues for global or semi-global state.