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.