← Back to all snippets
JAVASCRIPT

Deep Component Communication with provide and inject

Master Vue 3's `provide` and `inject` for efficient dependency injection, allowing data to be passed down deeply nested components without prop drilling.

import { defineComponent, provide, inject, ref } from 'vue';

// Parent Component
const ParentComponent = defineComponent({
  setup() {
    const theme = ref('dark');
    const toggleTheme = () => {
      theme.value = theme.value === 'dark' ? 'light' : 'dark';
    };

    // Provide a reactive value and a method
    provide('appTheme', theme);
    provide('toggleTheme', toggleTheme);

    return { theme, toggleTheme };
  },
  template: `
    <div :class="theme">
      <h2>Parent Component (Theme: {{ theme }})</h2>
      <button @click="toggleTheme">Toggle Theme</button>
      <MiddleComponent />
    </div>
  `
});

// Middle Component (can be many levels deep)
const MiddleComponent = defineComponent({
  template: `
    <div style="margin-left: 20px; border: 1px solid gray; padding: 10px;">
      <h3>Middle Component</h3>
      <ChildComponent />
    </div>
  `
});

// Child Component
const ChildComponent = defineComponent({
  setup() {
    // Inject the provided values
    const theme = inject('appTheme', 'default'); // 'default' is a fallback
    const toggleTheme = inject('toggleTheme');

    return { theme, toggleTheme };
  },
  template: `
    <div style="margin-left: 20px;">
      <h4>Child Component</h4>
      <p>Current Theme (Injected): {{ theme }}</p>
      <button v-if="toggleTheme" @click="toggleTheme">Toggle Theme from Child</button>
      <p v-else>Toggle Theme function not provided.</p>
    </div>
  `
});

export default ParentComponent;

/*
<template>
  <ParentComponent />
</template>
*/
How it works: This snippet demonstrates Vue 3's `provide` and `inject` features for dependency injection. The `ParentComponent` uses `provide` to make reactive data (`theme`) and a method (`toggleTheme`) available to its descendants. Deeply nested components, like `ChildComponent`, can then use `inject` to access these provided values without needing to pass them explicitly through props at each level, effectively solving prop drilling issues for global or semi-global state.

Need help integrating this into your project?

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

Hire DigitalCodeLabs