← Back to all snippets
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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs