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.