JAVASCRIPT
Deep Data Passing with Provide/Inject in Vue 3
Master `provide` and `inject` in Vue 3 to effortlessly pass data down through deeply nested components without prop drilling, maintaining clean component interfaces.
// App.vue (Parent Component providing data)
<template>
<div>
<h1>App Component (Theme Provider)</h1>
<button @click="toggleTheme">Toggle Theme</button>
<p>Current Theme in App: {{ currentTheme }}</p>
<DeepChild />
</div>
</template>
<script setup>
import { ref, provide } from 'vue';
import DeepChild from './components/DeepChild.vue';
const currentTheme = ref('light');
const toggleTheme = () => {
currentTheme.value = currentTheme.value === 'light' ? 'dark' : 'light';
};
// Provide the theme and a method to change it
provide('theme', currentTheme);
provide('toggleTheme', toggleTheme);
</script>
// components/DeepChild.vue (Intermediate component, just passes through)
<template>
<div class="deep-child">
<h2>Deep Child Component</h2>
<GrandChild />
</div>
</template>
<script setup>
import GrandChild from './GrandChild.vue';
</script>
<style scoped>
.deep-child {
border: 1px dashed #ccc;
padding: 10px;
margin-top: 10px;
}
</style>
// components/GrandChild.vue (Deeply nested component injecting data)
<template>
<div :class="['grand-child', theme]">
<h3>Grand Child Component</h3>
<p>Injected Theme: {{ theme }}</p>
<button @click="toggleTheme">Change Theme from Grand Child</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the provided values
const theme = inject('theme', 'default-theme'); // 'default-theme' is a fallback
const toggleTheme = inject('toggleTheme');
</script>
<style scoped>
.grand-child {
border: 1px solid #007bff;
padding: 10px;
margin-top: 10px;
}
.grand-child.light {
background-color: #f0f8ff;
color: black;
}
.grand-child.dark {
background-color: #343a40;
color: white;
}
</style>
How it works: This snippet illustrates Vue 3's `provide` and `inject` mechanism, a powerful alternative to prop drilling for passing data down through an arbitrary number of nested components. The parent component (`App.vue`) `provide`s a reactive `currentTheme` and a `toggleTheme` method using unique keys. Deeply nested components (like `GrandChild.vue`) can then `inject` these values directly, without intermediate components (`DeepChild.vue`) needing to pass them down via props. This simplifies component interfaces and enhances maintainability for complex component trees.