Dependency injection helps you share data or functions between components without passing them through many layers. It makes your code cleaner and easier to manage.
Dependency injection patterns in Vue
import { provide, inject } from 'vue' // In a parent or ancestor component provide('keyName', value) // In a child or descendant component const value = inject('keyName')
provide sets a value that descendants can access.
inject lets a component receive that value by the same key.
import { provide } from 'vue' export default { setup() { provide('color', 'blue') } }
import { inject } from 'vue' export default { setup() { const color = inject('color') return { color } } }
import { provide, inject } from 'vue' // Parent export default { setup() { const user = { name: 'Alice' } provide('user', user) } } // Child export default { setup() { const user = inject('user') return { user } } }
The parent component provides a theme object with color and font size. The child component injects this theme and uses it to style its text.
<template>
<div>
<h2>Parent Component</h2>
<ChildComponent />
</div>
</template>
<script setup>
import { provide } from 'vue'
import ChildComponent from './ChildComponent.vue'
const theme = { color: 'teal', fontSize: '1.2rem' }
provide('theme', theme)
</script>
<!-- ChildComponent.vue -->
<template>
<div :style="{ color: theme.color, fontSize: theme.fontSize }">
This text uses the injected theme.
</div>
</template>
<script setup>
import { inject } from 'vue'
const theme = inject('theme')
</script>If the injected key is not found, inject returns undefined unless you provide a default value.
You can provide default values like inject('key', defaultValue) to avoid errors.
Dependency injection works only between ancestor and descendant components, not siblings.
Dependency injection shares data or functions between components without prop drilling.
Use provide in an ancestor and inject in descendants.
This pattern keeps your code clean and easier to maintain.
Practice
provide and inject in Vue?Solution
Step 1: Understand the role of provide/inject
They allow sharing data or functions from a parent component to its descendants without passing props through every intermediate component.Step 2: Compare with other options
The other options relate to defining routes, creating global CSS styles, and handling component lifecycle hooks, which are unrelated to provide/inject.Final Answer:
To share data or functions between components without passing props manually -> Option BQuick Check:
Dependency injection = share data without props [OK]
- Confusing provide/inject with props or events
- Thinking provide/inject manages styles or routing
- Assuming provide/inject replaces Vuex or global state
Solution
Step 1: Identify provide syntax in Composition API
In Vue 3 Composition API, you call provide('key', value) inside setup() to share data.Step 2: Check other options
const value = inject('key') is for injection, not providing. this.provide('key', value) uses this which is not used in setup(). inject('key', value) is incorrect because inject does not provide values.Final Answer:
provide('key', value) -> Option CQuick Check:
Provide = provide('key', value) [OK]
- Using inject instead of provide to share data
- Trying to call provide on this inside setup()
- Confusing provide syntax with options API methods
import { provide, inject } from 'vue';
const Parent = {
setup() {
provide('message', 'Hello from parent')
}
}
const Child = {
setup() {
const msg = inject('message')
console.log(msg)
}
}Solution
Step 1: Understand provide/inject behavior
The parent provides the string 'Hello from parent' with key 'message'. The child injects this key and receives the value.Step 2: Predict console output
Since the child injects the provided key correctly, it logs 'Hello from parent'.Final Answer:
'Hello from parent' -> Option DQuick Check:
Inject returns provided value = 'Hello from parent' [OK]
- Expecting undefined if no return in setup
- Confusing provide with returning values
- Assuming inject returns null if key exists
import { provide, inject } from 'vue';
const Parent = {
setup() {
provide('data', 123)
}
}
const Child = {
setup() {
const data = inject('data')
console.log(data)
}
}Solution
Step 1: Check provide usage
Provide is correctly called inside setup() with key 'data' and value 123.Step 2: Check inject usage
Inject is called correctly but without a default value. If the key is missing, it returns undefined, which might cause issues.Final Answer:
inject is missing a default value, may cause undefined -> Option AQuick Check:
Inject without default can be undefined [OK]
- Thinking provide must return an object
- Believing inject can't be used in setup
- Assuming provide is outside setup here
Solution
Step 1: Understand reactive sharing with provide/inject
Providing a reactive object directly shares its reactivity, so descendants see updates.Step 2: Evaluate options for reactivity
Provide a reactive object usingprovide('state', reactiveObj)and inject it normally in the grandchild correctly provides a reactive object and injects it normally, preserving reactivity. Provide a plain object and inject it with a default value in the grandchild uses a plain object, losing reactivity. Provide a reactive object but inject it insideonMountedhook in the grandchild delays injection unnecessarily. Provide a reactive object but convert it to a ref before injecting converts reactive to ref, which is unnecessary and may cause confusion.Final Answer:
Provide a reactive object using provide('state', reactiveObj) and inject it normally in the grandchild -> Option AQuick Check:
Reactive object provided and injected keeps reactivity [OK]
- Providing plain objects losing reactivity
- Injecting inside lifecycle hooks unnecessarily
- Converting reactive to ref before injecting
Ready to prove it?
Pass the test and this pattern moves unknown
