0
# Injection System
1
2
Vue injection keys for providing themes and configuration options to child components. Enables consistent theming and configuration across component hierarchies.
3
4
## Capabilities
5
6
### Theme Injection
7
8
Provides chart theme to child components, allowing consistent theming across multiple charts.
9
10
```typescript { .api }
11
/**
12
* Injection key for chart theme
13
* Use with Vue's provide/inject to share themes across components
14
*/
15
declare const THEME_KEY: InjectionKey<ThemeInjection>;
16
17
type ThemeInjection = Injection<Theme>;
18
type Theme = NonNullable<Parameters<typeof init>[1]>;
19
type Injection<T> = T | null | Ref<T | null> | { value: T | null };
20
```
21
22
**Usage Examples:**
23
24
```vue
25
<!-- Parent component providing theme -->
26
<template>
27
<div class="dashboard">
28
<v-chart :option="chart1Option" />
29
<v-chart :option="chart2Option" />
30
</div>
31
</template>
32
33
<script setup>
34
import { provide } from "vue";
35
import { THEME_KEY } from "vue-echarts";
36
37
// Provide theme to all child charts
38
provide(THEME_KEY, "dark");
39
40
// Or provide reactive theme
41
const currentTheme = ref("light");
42
provide(THEME_KEY, currentTheme);
43
44
// Or provide theme object
45
const customTheme = {
46
backgroundColor: "#1e1e1e",
47
textStyle: { color: "#fff" }
48
};
49
provide(THEME_KEY, customTheme);
50
</script>
51
```
52
53
```vue
54
<!-- Child component consuming theme -->
55
<template>
56
<v-chart :option="option" />
57
<!-- Theme will be automatically applied -->
58
</template>
59
60
<script setup>
61
import { inject } from "vue";
62
import { THEME_KEY } from "vue-echarts";
63
64
// Access injected theme if needed
65
const theme = inject(THEME_KEY, null);
66
console.log("Current theme:", theme);
67
</script>
68
```
69
70
### Init Options Injection
71
72
Provides ECharts initialization options to child components.
73
74
```typescript { .api }
75
/**
76
* Injection key for ECharts initialization options
77
* Use with Vue's provide/inject to share init options
78
*/
79
declare const INIT_OPTIONS_KEY: InjectionKey<InitOptionsInjection>;
80
81
type InitOptionsInjection = Injection<InitOptions>;
82
type InitOptions = NonNullable<Parameters<typeof init>[2]>;
83
```
84
85
**Usage Examples:**
86
87
```vue
88
<!-- Parent providing init options -->
89
<script setup>
90
import { provide } from "vue";
91
import { INIT_OPTIONS_KEY } from "vue-echarts";
92
93
const initOptions = {
94
renderer: "canvas",
95
devicePixelRatio: 2,
96
width: "auto",
97
height: "auto",
98
locale: "EN"
99
};
100
101
provide(INIT_OPTIONS_KEY, initOptions);
102
</script>
103
```
104
105
### Update Options Injection
106
107
Provides chart update options to child components.
108
109
```typescript { .api }
110
/**
111
* Injection key for chart update options
112
* Controls how charts update when options change
113
*/
114
declare const UPDATE_OPTIONS_KEY: InjectionKey<UpdateOptionsInjection>;
115
116
type UpdateOptionsInjection = Injection<UpdateOptions>;
117
type UpdateOptions = SetOptionOpts;
118
```
119
120
**Usage Examples:**
121
122
```vue
123
<!-- Parent providing update options -->
124
<script setup>
125
import { provide } from "vue";
126
import { UPDATE_OPTIONS_KEY } from "vue-echarts";
127
128
const updateOptions = {
129
notMerge: false,
130
replaceMerge: undefined,
131
lazyUpdate: false
132
};
133
134
provide(UPDATE_OPTIONS_KEY, updateOptions);
135
</script>
136
```
137
138
### Loading Options Injection
139
140
Provides loading animation options to child components.
141
142
```typescript { .api }
143
/**
144
* Injection key for loading animation options
145
* Configures loading state appearance across charts
146
*/
147
declare const LOADING_OPTIONS_KEY: InjectionKey<LoadingOptionsInjection>;
148
149
type LoadingOptionsInjection = Injection<LoadingOptions>;
150
151
interface LoadingOptions {
152
text?: string;
153
textColor?: string;
154
fontSize?: number | string;
155
fontWeight?: number | string;
156
fontStyle?: string;
157
fontFamily?: string;
158
maskColor?: string;
159
showSpinner?: boolean;
160
color?: string;
161
spinnerRadius?: number;
162
lineWidth?: number;
163
zlevel?: number;
164
}
165
```
166
167
**Usage Examples:**
168
169
```vue
170
<!-- Parent providing loading options -->
171
<script setup>
172
import { provide } from "vue";
173
import { LOADING_OPTIONS_KEY } from "vue-echarts";
174
175
const loadingOptions = {
176
text: "Loading data...",
177
textColor: "#ffffff",
178
fontSize: 14,
179
maskColor: "rgba(0, 0, 0, 0.7)",
180
showSpinner: true,
181
color: "#409eff",
182
spinnerRadius: 10,
183
lineWidth: 2
184
};
185
186
provide(LOADING_OPTIONS_KEY, loadingOptions);
187
</script>
188
```
189
190
### Complete Injection Setup
191
192
Setting up all injection providers in a root component:
193
194
```vue
195
<!-- Root dashboard component -->
196
<template>
197
<div class="dashboard">
198
<theme-switcher @change="handleThemeChange" />
199
<chart-grid>
200
<v-chart v-for="chart in charts" :key="chart.id" :option="chart.option" />
201
</chart-grid>
202
</div>
203
</template>
204
205
<script setup>
206
import { provide, ref } from "vue";
207
import {
208
THEME_KEY,
209
INIT_OPTIONS_KEY,
210
UPDATE_OPTIONS_KEY,
211
LOADING_OPTIONS_KEY
212
} from "vue-echarts";
213
214
// Reactive theme
215
const currentTheme = ref("light");
216
217
// Static configuration
218
const initOptions = {
219
renderer: "canvas",
220
devicePixelRatio: window.devicePixelRatio || 1
221
};
222
223
const updateOptions = {
224
notMerge: false,
225
lazyUpdate: true
226
};
227
228
const loadingOptions = {
229
text: "Loading...",
230
showSpinner: true,
231
color: "#409eff"
232
};
233
234
// Provide all options
235
provide(THEME_KEY, currentTheme);
236
provide(INIT_OPTIONS_KEY, initOptions);
237
provide(UPDATE_OPTIONS_KEY, updateOptions);
238
provide(LOADING_OPTIONS_KEY, loadingOptions);
239
240
function handleThemeChange(theme) {
241
currentTheme.value = theme;
242
// All child charts will automatically update
243
}
244
</script>
245
```
246
247
### Nested Injection
248
249
Child components can override parent injections:
250
251
```vue
252
<!-- Parent component -->
253
<script setup>
254
import { provide } from "vue";
255
import { THEME_KEY } from "vue-echarts";
256
257
provide(THEME_KEY, "dark"); // Default theme
258
</script>
259
260
<template>
261
<div>
262
<v-chart :option="chart1" /> <!-- Uses dark theme -->
263
<special-chart-section />
264
</div>
265
</template>
266
```
267
268
```vue
269
<!-- Child component overriding theme -->
270
<script setup>
271
import { provide } from "vue";
272
import { THEME_KEY } from "vue-echarts";
273
274
provide(THEME_KEY, "light"); // Override with light theme
275
</script>
276
277
<template>
278
<div class="special-section">
279
<v-chart :option="chart2" /> <!-- Uses light theme -->
280
<v-chart :option="chart3" /> <!-- Uses light theme -->
281
</div>
282
</template>
283
```
284
285
### Injection Utilities
286
287
Accessing injected values in custom components:
288
289
```vue
290
<script setup>
291
import { inject, computed } from "vue";
292
import { THEME_KEY, INIT_OPTIONS_KEY } from "vue-echarts";
293
294
// Inject with defaults
295
const theme = inject(THEME_KEY, "light");
296
const initOptions = inject(INIT_OPTIONS_KEY, {});
297
298
// Use in computed properties
299
const isDarkTheme = computed(() => {
300
const themeValue = unref(theme);
301
return themeValue === "dark" ||
302
(typeof themeValue === "object" && themeValue?.backgroundColor === "#1e1e1e");
303
});
304
305
// Apply conditional styling
306
const containerClass = computed(() => ({
307
"dark-container": isDarkTheme.value,
308
"light-container": !isDarkTheme.value
309
}));
310
</script>
311
```
312
313
### Vue 2 Compatibility
314
315
For Vue 2, when providing reactive values, wrap them in objects:
316
317
```vue
318
<!-- Vue 2 dynamic injection -->
319
<script>
320
export default {
321
data() {
322
return {
323
themeWrapper: { value: "light" },
324
initOptionsWrapper: {
325
value: {
326
renderer: "canvas",
327
devicePixelRatio: 2
328
}
329
}
330
};
331
},
332
provide() {
333
return {
334
[THEME_KEY]: this.themeWrapper,
335
[INIT_OPTIONS_KEY]: this.initOptionsWrapper
336
};
337
},
338
methods: {
339
switchTheme() {
340
this.themeWrapper.value = this.themeWrapper.value === "light" ? "dark" : "light";
341
}
342
}
343
};
344
</script>
345
```
346
347
### Performance Considerations
348
349
When providing complex objects, consider memoization to avoid unnecessary re-renders:
350
351
```vue
352
<script setup>
353
import { provide, computed, ref } from "vue";
354
import { INIT_OPTIONS_KEY, UPDATE_OPTIONS_KEY } from "vue-echarts";
355
356
const devicePixelRatio = ref(window.devicePixelRatio || 1);
357
const locale = ref("EN");
358
359
// Memoized init options
360
const initOptions = computed(() => ({
361
renderer: "canvas",
362
devicePixelRatio: devicePixelRatio.value,
363
locale: locale.value
364
}));
365
366
// Static update options (no need to compute)
367
const updateOptions = {
368
notMerge: false,
369
lazyUpdate: true,
370
silent: false
371
};
372
373
provide(INIT_OPTIONS_KEY, initOptions);
374
provide(UPDATE_OPTIONS_KEY, updateOptions);
375
376
// Update pixel ratio on window changes
377
window.addEventListener("resize", () => {
378
devicePixelRatio.value = window.devicePixelRatio || 1;
379
});
380
</script>
381
```