0
# Dependency Injection
1
2
Provide and Inject decorators for parent-child component communication and dependency injection patterns. These decorators implement Vue's provide/inject mechanism using class-based syntax, enabling dependency injection across component hierarchies.
3
4
## Capabilities
5
6
### Provide Decorator
7
8
Provides dependency injection values to child components, making values available to descendant components in the component tree.
9
10
```typescript { .api }
11
/**
12
* Provides dependency injection values to child components
13
* @param key - Injection key (optional, defaults to property name)
14
* @returns Property decorator function
15
*/
16
function Provide(key?: string | symbol): PropertyDecorator;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { Vue, Component, Provide } from "vue-property-decorator";
23
24
@Component
25
export default class ParentComponent extends Vue {
26
// Provide with default key (property name)
27
@Provide()
28
message = "Hello from parent";
29
30
// Provide with custom key
31
@Provide("customKey")
32
customData = { value: 42 };
33
34
// Provide with symbol key
35
private static THEME_KEY = Symbol("theme");
36
37
@Provide(ParentComponent.THEME_KEY)
38
theme = "dark";
39
40
// Provide computed value
41
@Provide("computedValue")
42
get computedValue() {
43
return `Computed: ${this.message}`;
44
}
45
}
46
```
47
48
### ProvideReactive Decorator
49
50
Provides reactive dependency injection values to child components, ensuring that changes in parent values automatically update in child components.
51
52
```typescript { .api }
53
/**
54
* Provides reactive dependency injection values to child components
55
* @param key - Injection key (optional, defaults to property name)
56
* @returns Property decorator function
57
*/
58
function ProvideReactive(key?: string | symbol): PropertyDecorator;
59
```
60
61
**Usage Examples:**
62
63
```typescript
64
import { Vue, Component, ProvideReactive } from "vue-property-decorator";
65
66
@Component
67
export default class ReactiveParent extends Vue {
68
// Reactive provide - children will update when this changes
69
@ProvideReactive()
70
counter = 0;
71
72
// Reactive provide with custom key
73
@ProvideReactive("sharedState")
74
state = {
75
user: null,
76
isLoggedIn: false
77
};
78
79
increment() {
80
this.counter++; // All injected children will receive the new value
81
}
82
83
login(user: any) {
84
this.state.user = user;
85
this.state.isLoggedIn = true; // Children will reactively update
86
}
87
}
88
```
89
90
### Inject Decorator
91
92
Injects dependencies from parent components, receiving values provided by ancestor components in the component tree.
93
94
```typescript { .api }
95
/**
96
* Injects dependencies from parent components
97
* @param options - InjectOptions object or InjectKey (optional, defaults to property name)
98
* @returns Property decorator function
99
*/
100
function Inject(options?: InjectOptions | InjectKey): PropertyDecorator;
101
102
interface InjectOptions {
103
from?: InjectKey;
104
default?: any;
105
}
106
107
type InjectKey = string | symbol;
108
```
109
110
**Usage Examples:**
111
112
```typescript
113
import { Vue, Component, Inject } from "vue-property-decorator";
114
115
@Component
116
export default class ChildComponent extends Vue {
117
// Inject with default key (property name)
118
@Inject()
119
message!: string;
120
121
// Inject with custom key
122
@Inject("customKey")
123
customData!: { value: number };
124
125
// Inject with default value
126
@Inject({ default: "fallback" })
127
optionalMessage!: string;
128
129
// Inject with different key and default
130
@Inject({ from: "parentTheme", default: "light" })
131
theme!: string;
132
133
// Inject symbol key
134
@Inject(Symbol.for("global-config"))
135
config!: any;
136
}
137
```
138
139
### InjectReactive Decorator
140
141
Injects reactive dependencies from parent components, automatically updating when parent provided values change.
142
143
```typescript { .api }
144
/**
145
* Injects reactive dependencies from parent components
146
* @param options - InjectOptions object or InjectKey (optional, defaults to property name)
147
* @returns Property decorator function
148
*/
149
function InjectReactive(options?: InjectOptions | InjectKey): PropertyDecorator;
150
```
151
152
**Usage Examples:**
153
154
```typescript
155
import { Vue, Component, InjectReactive, Watch } from "vue-property-decorator";
156
157
@Component
158
export default class ReactiveChild extends Vue {
159
// Reactive inject - will update when parent changes the value
160
@InjectReactive()
161
counter!: number;
162
163
// Reactive inject with custom configuration
164
@InjectReactive({ from: "sharedState", default: null })
165
state!: { user: any; isLoggedIn: boolean } | null;
166
167
// Watch reactive injected values
168
@Watch("counter")
169
onCounterChanged(newVal: number, oldVal: number) {
170
console.log(`Counter changed from ${oldVal} to ${newVal}`);
171
}
172
173
@Watch("state", { deep: true })
174
onStateChanged(newState: any) {
175
if (newState && newState.isLoggedIn) {
176
console.log("User logged in:", newState.user);
177
}
178
}
179
}
180
```
181
182
## Advanced Usage Patterns
183
184
### Provider-Consumer Pattern
185
186
```typescript
187
// Provider component
188
@Component
189
export default class DataProvider extends Vue {
190
@ProvideReactive("dataService")
191
dataService = {
192
items: [],
193
loading: false,
194
195
async fetchItems() {
196
this.loading = true;
197
try {
198
this.items = await api.getItems();
199
} finally {
200
this.loading = false;
201
}
202
}
203
};
204
}
205
206
// Consumer component
207
@Component
208
export default class DataConsumer extends Vue {
209
@InjectReactive("dataService")
210
dataService!: any;
211
212
mounted() {
213
this.dataService.fetchItems();
214
}
215
}
216
```
217
218
### Configuration Injection
219
220
```typescript
221
// App root component
222
@Component
223
export default class App extends Vue {
224
@Provide("appConfig")
225
config = {
226
apiUrl: process.env.VUE_APP_API_URL,
227
theme: "default",
228
features: {
229
darkMode: true,
230
notifications: true
231
}
232
};
233
}
234
235
// Deeply nested component
236
@Component
237
export default class FeatureComponent extends Vue {
238
@Inject("appConfig")
239
config!: any;
240
241
get isDarkModeEnabled() {
242
return this.config.features.darkMode;
243
}
244
}
245
```
246
247
## Types
248
249
```typescript { .api }
250
interface InjectOptions {
251
from?: InjectKey;
252
default?: any;
253
}
254
255
type InjectKey = string | symbol;
256
type PropertyDecorator = (target: any, propertyKey: string | symbol) => void;
257
```