JAVASCRIPT
Dependency Injection with `provide` and `inject`
Master Vue 3's `provide` and `inject` to efficiently pass data down the component tree, avoiding prop drilling and creating flexible component architectures.
// ParentComponent.vue
<template>
<div>
<h1>Parent Component</h1>
<ChildComponent />
</div>
</template>
<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const theme = ref('dark');
const toggleTheme = () => {
theme.value = theme.value === 'dark' ? 'light' : 'dark';
};
provide('appTheme', theme);
provide('toggleAppTheme', toggleTheme);
</script>
// ChildComponent.vue
<template>
<div :class="injectedTheme">
<h2>Child Component</h2>
<GrandchildComponent />
</div>
</template>
<script setup>
import { inject } from 'vue';
import GrandchildComponent from './GrandchildComponent.vue';
const injectedTheme = inject('appTheme', 'light'); // 'light' is a default value
// No need to inject toggleAppTheme here if not used
</script>
// GrandchildComponent.vue
<template>
<div :class="injectedTheme">
<h3>Grandchild Component</h3>
<p>Current theme: {{ injectedTheme }}</p>
<button @click="toggleTheme">Toggle Theme</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
const injectedTheme = inject('appTheme');
const toggleTheme = inject('toggleAppTheme');
</script>
How it works: This snippet demonstrates Vue 3's `provide` and `inject` mechanism for dependency injection. The `ParentComponent` uses `provide` to make `appTheme` (a reactive ref) and `toggleAppTheme` (a function) available to all its descendants. `ChildComponent` and `GrandchildComponent` then use `inject` to consume these provided values without needing them passed as props through intermediate components. This pattern is ideal for global configurations, themes, or services that many components might need.