← Back to all snippets
JAVASCRIPT

Using Provide/Inject for Dependency Injection in Vue 3

Understand how Vue 3's `provide` and `inject` features enable dependency injection, allowing data to be passed down through deeply nested components.

// src/App.vue (Parent Component)
<template>
  <div>
    <h1>Provide/Inject Example</h1>
    <p>Parent Component: {{ message }}</p>
    <GrandparentComponent />
  </div>
</template>

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

const message = ref('Hello from App.vue (Parent)');
const count = ref(0);

// Provide data to all descendants
provide('appMessage', message);
provide('appCount', count);

const incrementCount = () => {
  count.value++;
};
provide('incrementAppCount', incrementCount);
</script>


// src/components/GrandparentComponent.vue
<template>
  <div style="border: 1px solid blue; padding: 10px; margin: 10px;">
    <h2>Grandparent Component</h2>
    <p>This component receives nothing directly from App.vue.</p>
    <ChildComponent />
  </div>
</template>

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


// src/components/ChildComponent.vue
<template>
  <div style="border: 1px solid green; padding: 10px; margin: 10px;">
    <h3>Child Component</h3>
    <p>Injected Message: {{ injectedMessage }}</p>
    <p>Injected Count: {{ injectedCount }}</p>
    <button @click="injectedIncrementCount">Increment Injected Count</button>
    <GrandchildComponent />
  </div>
</template>

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

const injectedMessage = inject('appMessage');
const injectedCount = inject('appCount');
const injectedIncrementCount = inject('incrementAppCount');
</script>


// src/components/GrandchildComponent.vue
<template>
  <div style="border: 1px solid red; padding: 10px; margin: 10px;">
    <h4>Grandchild Component</h4>
    <p>Injected Message: {{ injectedMessage }}</p>
    <p>Injected Count (read-only): {{ injectedCount }}</p>
  </div>
</template>

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

const injectedMessage = inject('appMessage');
const injectedCount = inject('appCount');
// No need to inject incrementAppCount if not used here
</script>
How it works: This snippet demonstrates Vue 3's `provide` and `inject` features for dependency injection, which simplifies passing data and functions down through deeply nested component hierarchies without 'prop drilling'. The `App.vue` parent component uses `provide` to make reactive data (`message`, `count`) and a function (`incrementCount`) available. Descendant components, like `ChildComponent` and `GrandchildComponent`, can then use `inject` to consume these provided values, regardless of how many layers deep they are, enabling cleaner component communication.

Need help integrating this into your project?

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

Hire DigitalCodeLabs