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.