← Back to all snippets
JAVASCRIPT

Vue 3 Provide/Inject for Deep Dependency Injection

Avoid prop drilling in Vue 3 by using `provide` and `inject` to pass data down deeply nested component trees, simplifying data flow management.

// App.vue (Parent Component)
<template>
  <div>
    <h1>App Component</h1>
    <p>Global Setting from App: {{ appSetting }}</p>
    <button @click="toggleSetting">Toggle App Setting</button>
    <MiddleComponent />
  </div>
</template>

<script setup>
import { ref, provide } from 'vue';
import MiddleComponent from './components/MiddleComponent.vue';

const appSetting = ref('light-theme');

function toggleSetting() {
  appSetting.value = appSetting.value === 'light-theme' ? 'dark-theme' : 'light-theme';
}

// Provide a reactive value
provide('theme-setting', appSetting);
provide('toggle-theme', toggleSetting);
</script>

// components/MiddleComponent.vue (Intermediate Component)
<template>
  <div style="border: 1px solid blue; padding: 10px; margin-top: 10px;">
    <h3>Middle Component</h3>
    <p>This component doesn't need the theme setting directly.</p>
    <GrandchildComponent />
  </div>
</template>

<script setup>
import GrandchildComponent from './GrandchildComponent.vue';
</script>

// components/GrandchildComponent.vue (Deeply Nested Component)
<template>
  <div style="border: 1px solid green; padding: 10px; margin-top: 10px;">
    <h4>Grandchild Component</h4>
    <p>Injected Theme: {{ injectedTheme }}</p>
    <button @click="injectedToggleTheme">Toggle from Grandchild</button>
  </div>
</template>

<script setup>
import { inject } from 'vue';

// Inject the provided values
const injectedTheme = inject('theme-setting');
const injectedToggleTheme = inject('toggle-theme');

// Can also provide a default value if not found:
// const anotherSetting = inject('non-existent-setting', 'default-value');
</script>
How it works: This snippet demonstrates the `provide` and `inject` pattern in Vue 3 for dependency injection. The parent component (`App.vue`) `provide`s a reactive `appSetting` and a `toggleSetting` function. The intermediate component (`MiddleComponent.vue`) doesn't need to know about these. The deeply nested `GrandchildComponent.vue` can then `inject` these values without needing them to be passed down through props at each level (prop drilling). This makes data sharing simpler and cleaner for deeply nested component trees.

Need help integrating this into your project?

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

Hire DigitalCodeLabs