JAVASCRIPT
Implementing Dependency Injection with Vue 3 Provide/Inject
Learn how to use Vue 3's `provide` and `inject` to pass data or functions down through a component tree without prop drilling, ideal for global configurations or services.
// main.js (or App.vue setup)
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
// App.vue (Parent Component providing a theme and a function)
<template>
<div :class="currentTheme">
<h1>App Component (Theme: {{ currentTheme }})</h1>
<button @click="toggleTheme">Toggle Theme</button>
<DeepChild />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import DeepChild from './DeepChild.vue';
const currentTheme = ref('light-theme');
const toggleTheme = () => {
currentTheme.value = currentTheme.value === 'light-theme' ? 'dark-theme' : 'light-theme';
};
// Provide the theme and the toggle function
provide('appTheme', currentTheme);
provide('toggleAppTheme', toggleTheme);
</script>
<style>
.light-theme { background-color: #f0f0f0; color: #333; padding: 20px; border-radius: 8px; }
.dark-theme { background-color: #333; color: #f0f0f0; padding: 20px; border-radius: 8px; }
</style>
// DeepChild.vue (Grandchild Component injecting and using the provided values)
<template>
<div :class="['child-box', injectedTheme]">
<h2>Deep Child Component</h2>
<p>Current theme from parent: {{ injectedTheme }}</p>
<button @click="injectedToggleTheme">Toggle Theme from Child</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the provided values
const injectedTheme = inject('appTheme', 'default-theme'); // 'default-theme' is a fallback
const injectedToggleTheme = inject('toggleAppTheme');
</script>
<style scoped>
.child-box { margin-top: 15px; padding: 15px; border: 1px dashed #666; }
</style>
How it works: `provide` and `inject` offer a dependency injection system in Vue 3. A parent component can `provide` data or methods, and any descendant component, regardless of how deep, can `inject` those provided values. This avoids "prop drilling" (passing props through many intermediate components) for common data or functionalities shared across a subtree, making it ideal for global configurations, themes, or utility functions.