JAVASCRIPT
Share Data Across Components with Vue 3 `provide` and `inject`
Learn how to use Vue 3's `provide` and `inject` to pass data down the component tree without prop drilling, perfect for deeply nested components.
// ParentComponent.vue
<template>
<div>
<h2>Parent Component</h2>
<p>Provided data: {{ parentData }}</p>
<button @click="parentData = 'New Data from Parent'">Update Provided Data</button>
<ChildComponent />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentData = ref('Data from Parent');
// Provide a reactive value
provide('my-key', parentData);
// Provide a static value (optional)
provide('static-key', 'This is a static value');
// Provide a function
provide('increment-func', () => {
alert('Function from parent called!');
// You could also modify parentData here if needed
});
</script>
// ChildComponent.vue
<template>
<div>
<h3>Child Component</h3>
<GrandchildComponent />
</div>
</template>
<script setup>
import GrandchildComponent from './GrandchildComponent.vue';
</script>
// GrandchildComponent.vue
<template>
<div>
<h4>Grandchild Component</h4>
<p>Injected data (reactive): {{ injectedData }}</p>
<p>Injected data (static): {{ injectedStaticData }}</p>
<button @click="callParentFunction">Call Parent Function</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the reactive value
const injectedData = inject('my-key');
// Inject the static value
const injectedStaticData = inject('static-key', 'Default if not provided'); // Optional: with default value
// Inject the function
const callParentFunction = inject('increment-func');
</script>
How it works: The `provide` and `inject` API in Vue 3 offers a way to pass data from an ancestor component down to any descendant component, no matter how deep, without explicitly passing props at each level (known as 'prop drilling'). `provide` is used in the parent to make data available, and `inject` is used in a descendant to retrieve that data. This is ideal for sharing global configurations, themes, or utility functions across a deeply nested component tree, creating a dependency injection system specific to your component hierarchy.