Provide / Inject
Dependency Injection
Provide and Inject enable dependency injection in Vue. They solve the problem of "props drilling" - passing props through many levels of components just to reach a deeply nested child.
With provide/inject, a parent component can serve as a dependency provider for all its descendants, regardless of how deep the component hierarchy is.
How It Works
A parent component uses provide() to make data available:
<script setup>
const theme = ref('dark')
provide('theme', theme)
</script>
Any descendant component can use inject() to receive that data:
<script setup>
const theme = inject('theme')
</script>
When to Use Provide/Inject
✅ Use provide/inject when:
- You have deeply nested components that need access to the same data
- Building reusable component libraries (like theme systems)
- Sharing global state that doesn't change often
❌ Avoid provide/inject when:
- You only need to pass data one level down (use props instead)
- You need complex state management (use Pinia instead)
- The data changes frequently and you need fine-grained reactivity tracking
Reactive Injection
To make injected values reactive, provide a ref or reactive object:
<script setup>
// Provider
const theme = ref('dark')
provide('theme', theme)
function toggleTheme() {
theme.value = theme.value === 'dark' ? 'light' : 'dark'
}
provide('toggleTheme', toggleTheme)
</script>
<script setup>
// Consumer
const theme = inject('theme')
const toggleTheme = inject('toggleTheme')
</script>
Challenge
Create a theme system using provide/inject:
- In
app.vue, create aThemeProvidercomponent that:- Provides a reactive
themeref (values: 'light' or 'dark') - Provides a
toggleThemefunction - Wraps the
ThemedButtoncomponents
- Provides a reactive
- Create a
ThemedButtoncomponent that:- Injects the
themevalue - Injects the
toggleThemefunction - Changes its appearance based on the theme
- Toggles the theme when clicked
- Injects the
- Create multiple
ThemedButtoncomponents to show they all share the same theme
Tip: Use provide('key', value) in the parent and inject('key') in descendants. Make sure to provide a ref for reactivity.
If you get stuck, you can check the solution by clicking the button below.
Provide/inject is powerful for building flexible component systems, but remember: for most cases, props are clearer and easier to debug. Use provide/inject when props drilling becomes unwieldy.