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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs