JAVASCRIPT
Deep Dependency Injection with Vue 3 Provide/Inject
Master Vue 3's `provide` and `inject` API to pass data and services deeply down your component tree without prop drilling, simplifying complex component communication.
// App.vue (Parent component)
<template>
<div>
<h1>Root Component</h1>
<p>Theme: {{ theme }}</p>
<button @click="toggleTheme">Toggle Theme</button>
<IntermediateComponent />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import IntermediateComponent from './components/IntermediateComponent.vue';
const theme = ref('light');
const toggleTheme = () => {
theme.value = theme.value === 'light' ? 'dark' : 'light';
};
// Provide a reactive value and a method
provide('appTheme', theme);
provide('toggleTheme', toggleTheme);
</script>
// components/IntermediateComponent.vue
<template>
<div style="border: 1px solid blue; padding: 10px; margin-top: 10px;">
<h2>Intermediate Component</h2>
<ChildComponent />
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
// This component doesn't need to know about 'appTheme' or 'toggleTheme'
</script>
// components/ChildComponent.vue (Grandchild component)
<template>
<div :class="['child-component', theme]">
<h3>Child Component</h3>
<p>Injected Theme: {{ theme }}</p>
<button @click="toggleTheme">Toggle Theme from Child</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the provided values
const theme = inject('appTheme');
const toggleTheme = inject('toggleTheme');
</script>
<style scoped>
.child-component {
padding: 10px;
border: 1px solid gray;
margin-top: 10px;
}
.light { background-color: #f0f0f0; color: #333; }
.dark { background-color: #333; color: #f0f0f0; }
</style>
How it works: Vue 3's `provide` and `inject` APIs offer a powerful alternative to prop drilling for passing data down a component tree. A parent component can `provide` a value (which can be reactive), and any descendant component, regardless of how deep, can `inject` that value. This snippet demonstrates providing a `theme` and a `toggleTheme` function from the root `App.vue` and injecting them into `ChildComponent.vue` (a grandchild), allowing it to consume and modify the theme without explicit prop passing through `IntermediateComponent.vue`.