JAVASCRIPT
Deep Dependency Injection with Provide and Inject
Utilize Vue 3's provide and inject functions to pass data down deeply nested component trees without prop drilling, simplifying component communication.
// ParentComponent.vue
<template>
<div>
<h1>Parent Component</h1>
<input type="text" v-model="userName" placeholder="Enter user name" />
<button @click="incrementCount">Increment Shared Count</button>
<ChildComponent />
</div>
</template>
<script setup>
import { ref, provide, computed } from 'vue';
import ChildComponent from './ChildComponent.vue';
const userName = ref('Alice');
const sharedCount = ref(0);
const incrementCount = () => {
sharedCount.value++;
};
// Provide a reactive value and a function
provide('userNameKey', computed(() => userName.value.toUpperCase())); // Provided as a computed ref
provide('sharedCountKey', sharedCount); // Provided as a ref
provide('incrementSharedCountKey', incrementCount);
// Provide a default theme setting, which can be overridden
provide('theme', 'light');
</script>
// ChildComponent.vue
<template>
<div style="border: 1px solid #ccc; padding: 10px; margin: 10px;">
<h2>Child Component</h2>
<GrandchildComponent />
</div>
</template>
<script setup>
import GrandchildComponent from './GrandchildComponent.vue';
</script>
// GrandchildComponent.vue
<template>
<div style="border: 1px dashed #eee; padding: 10px;">
<h3>Grandchild Component</h3>
<p>User Name (from Parent): {{ upperCaseUserName }}</p>
<p>Shared Count (from Parent): {{ sharedCountValue }}</p>
<button @click="incrementSharedCount">Increment from Grandchild</button>
<p>Current Theme (from Parent or default): {{ currentTheme }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
// Inject the provided values
const upperCaseUserName = inject('userNameKey', 'N/A'); // With a default value
const sharedCountValue = inject('sharedCountKey', ref(0)); // Injecting a ref, provide a ref as default
const incrementSharedCount = inject('incrementSharedCountKey', () => console.warn('Increment function not provided!'));
const currentTheme = inject('theme', 'dark'); // Inject with a default if not provided
</script>
How it works: This snippet illustrates Vue 3's `provide` and `inject` functions for dependency injection. `provide` in `ParentComponent.vue` allows data and functions to be made available to all its descendants, regardless of how deep they are nested, without explicit prop drilling. `inject` in `GrandchildComponent.vue` then consumes these provided values using specific keys. This pattern is ideal for global settings, themes, or utility functions that many components might need, ensuring a clean separation of concerns and reducing boilerplate for prop passing.