JAVASCRIPT

Efficient Data Sharing with Vue 3 `provide` and `inject`

Learn to effectively share data across deeply nested components in Vue 3 using the `provide` and `inject` API, avoiding prop drilling for cleaner and more maintainable code.

// ParentComponent.vue
<template>
  <div>
    <h1>Parent Component</h1>
    <p>Theme: {{ currentTheme }}</p>
    <button @click="toggleTheme">Toggle Theme</button>
    <NestedComponent />
  </div>
</template>

<script setup>
import { ref, provide, readonly } from 'vue';
import NestedComponent from './NestedComponent.vue';

const currentTheme = ref('light');

const toggleTheme = () => {
  currentTheme.value = currentTheme.value === 'light' ? 'dark' : 'light';
};

// Provide the reactive theme and a method to update it
// Using readonly for the theme to prevent direct modification in child components
provide('appTheme', readonly(currentTheme));
provide('toggleAppTheme', toggleTheme);
</script>

// NestedComponent.vue
<template>
  <div :style="{ backgroundColor: theme === 'dark' ? '#333' : '#eee', color: theme === 'dark' ? '#eee' : '#333' }">
    <h2>Nested Component</h2>
    <DeeplyNestedComponent />
  </div>
</template>

<script setup>
import { inject } from 'vue';
import DeeplyNestedComponent from './DeeplyNestedComponent.vue';

// Inject the provided theme value
const theme = inject('appTheme');
</script>

// DeeplyNestedComponent.vue
<template>
  <div :style="{ border: '1px solid ' + (theme === 'dark' ? 'white' : 'black'), padding: '10px' }">
    <h3>Deeply Nested Component</h3>
    <p>Injected Theme: {{ theme }}</p>
    <button @click="toggleTheme">Toggle Theme from Deep Nest</button>
  </div>
</template>

<script setup>
import { inject } from 'vue';

// Inject the provided theme value and the toggle method
const theme = inject('appTheme');
const toggleTheme = inject('toggleAppTheme');

// Optional: Provide a default value if not found
// const theme = inject('appTheme', 'default_light_theme');
</script>
How it works: This snippet demonstrates Vue 3's `provide` and `inject` API for efficient data sharing between components, especially useful for deeply nested hierarchies to avoid "prop drilling." A parent component uses `provide` to make reactive data (`currentTheme` using `readonly` to prevent direct modification by children) and methods (`toggleTheme`) available. Any descendant component, regardless of its nesting level, can then use `inject` to consume these provided values. This creates a flexible dependency injection system, making components more modular and easier to maintain.

Need help integrating this into your project?

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

Hire DigitalCodeLabs