0
# Composition API
1
2
Universal access to Composition API functions that work across Vue 2 (with @vue/composition-api) and Vue 3. Vue Demi automatically provides the appropriate implementation based on the detected Vue version.
3
4
## Capabilities
5
6
### Safe Installation
7
8
Ensures the Composition API plugin is properly installed. This is a no-op in Vue 3 but safely installs @vue/composition-api in Vue 2 environments.
9
10
```typescript { .api }
11
/**
12
* Safe installation of Composition API plugin
13
* No-op in Vue 3, installs @vue/composition-api in Vue 2
14
* @param vue - Optional Vue constructor (Vue 2 only), ignored in Vue 3
15
*/
16
declare function install(vue?: typeof Vue): void; // Vue 2: (vue?: typeof Vue), Vue 3: () => void
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { install } from "vue-demi";
23
24
// Ensure Composition API is available
25
install();
26
27
// Or with specific Vue instance
28
import Vue from 'vue';
29
install(Vue);
30
31
// Safe to call multiple times
32
install();
33
install(); // No-op if already installed
34
```
35
36
### Universal Composition API
37
38
All Composition API functions are re-exported from vue-demi, providing a universal interface that works across Vue versions.
39
40
```typescript { .api }
41
// Core reactivity
42
export function ref<T>(value: T): Ref<T>;
43
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;
44
export function computed<T>(getter: () => T): ComputedRef<T>;
45
export function readonly<T>(target: T): DeepReadonly<T>;
46
47
// Watchers
48
export function watch<T>(
49
source: WatchSource<T>,
50
callback: WatchCallback<T>,
51
options?: WatchOptions
52
): WatchStopHandle;
53
54
export function watchEffect(
55
effect: WatchEffect,
56
options?: WatchOptionsBase
57
): WatchStopHandle;
58
59
// Lifecycle hooks
60
export function onMounted(hook: () => any): void;
61
export function onUpdated(hook: () => any): void;
62
export function onUnmounted(hook: () => any): void;
63
export function onBeforeMount(hook: () => any): void;
64
export function onBeforeUpdate(hook: () => any): void;
65
export function onBeforeUnmount(hook: () => any): void;
66
67
// Dependency injection
68
export function provide<T>(key: InjectionKey<T> | string, value: T): void;
69
export function inject<T>(key: InjectionKey<T> | string): T | undefined;
70
export function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T;
71
72
// Component utilities
73
export function getCurrentInstance(): ComponentInternalInstance | null;
74
export function nextTick(fn?: () => void): Promise<void>;
75
export function hasInjectionContext(): boolean;
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
import {
82
ref,
83
reactive,
84
computed,
85
watch,
86
onMounted,
87
install
88
} from "vue-demi";
89
90
// Ensure Composition API is installed
91
install();
92
93
export default {
94
setup() {
95
// Reactive state
96
const count = ref(0);
97
const user = reactive({
98
name: 'John',
99
email: 'john@example.com'
100
});
101
102
// Computed values
103
const doubleCount = computed(() => count.value * 2);
104
105
// Watchers
106
watch(count, (newVal, oldVal) => {
107
console.log(`Count changed from ${oldVal} to ${newVal}`);
108
});
109
110
// Lifecycle
111
onMounted(() => {
112
console.log('Component mounted');
113
});
114
115
return {
116
count,
117
user,
118
doubleCount
119
};
120
}
121
};
122
```
123
124
### Vue 3 Component Mocks (Vue 2 only)
125
126
In Vue 2 environments, Vue 3 specific components are provided as mock implementations that throw helpful errors to prevent runtime issues.
127
128
```typescript { .api }
129
/**
130
* Mock components for Vue 3 features not available in Vue 2
131
* These throw descriptive errors when used in Vue 2
132
*/
133
export declare const Fragment: Component;
134
export declare const Transition: Component;
135
export declare const TransitionGroup: Component;
136
export declare const Teleport: Component;
137
export declare const Suspense: Component;
138
export declare const KeepAlive: Component;
139
```
140
141
**Usage Examples:**
142
143
```typescript
144
import { Fragment, isVue2 } from "vue-demi";
145
146
// Safe conditional usage
147
const MyComponent = {
148
setup() {
149
if (isVue2) {
150
// Vue 2 implementation without Fragment
151
return () => h('div', [
152
h('p', 'First paragraph'),
153
h('p', 'Second paragraph')
154
]);
155
} else {
156
// Vue 3 implementation with Fragment
157
return () => h(Fragment, [
158
h('p', 'First paragraph'),
159
h('p', 'Second paragraph')
160
]);
161
}
162
}
163
};
164
165
// This would throw an error in Vue 2:
166
// [vue-demi] Fragment is not supported in Vue 2. It's provided to avoid compiler errors.
167
```
168
169
### Injection Context Check
170
171
Utility to check if injection context is available, useful for safely using provide/inject.
172
173
```typescript { .api }
174
/**
175
* Check if injection context exists
176
* Falls back to getCurrentInstance() check
177
* @returns boolean indicating if injection context is available
178
*/
179
export function hasInjectionContext(): boolean;
180
```
181
182
**Usage Examples:**
183
184
```typescript
185
import { hasInjectionContext, inject, provide } from "vue-demi";
186
187
// Safe injection usage
188
function useTheme() {
189
if (hasInjectionContext()) {
190
return inject('theme', 'light');
191
}
192
return 'light'; // fallback
193
}
194
195
// Conditional provide/inject
196
export default {
197
setup() {
198
if (hasInjectionContext()) {
199
provide('theme', 'dark');
200
}
201
202
const theme = useTheme();
203
return { theme };
204
}
205
};
206
```
207
208
### Vue Warning Utility (Vue 2.7 only)
209
210
Vue 2.7 provides access to Vue's internal warning utility for development debugging.
211
212
```typescript { .api }
213
/**
214
* Vue warning function (Vue 2.7 only)
215
* Emits development warnings with optional component context
216
* @param msg - Warning message to display
217
* @param vm - Optional component instance for context
218
*/
219
export declare function warn(msg: string, vm?: Component | null): void;
220
```
221
222
**Usage Examples:**
223
224
```typescript
225
import { warn, isVue2, version } from "vue-demi";
226
227
// Development warnings (Vue 2.7 only)
228
export default {
229
setup() {
230
if (process.env.NODE_ENV !== 'production' && isVue2 && version?.startsWith('2.7')) {
231
// Emit warning with component context
232
warn('This is a development warning', getCurrentInstance());
233
234
// Simple warning
235
warn('Configuration issue detected');
236
}
237
238
return {};
239
}
240
};
241
242
// Conditional warning utility
243
function devWarn(message: string, component?: any) {
244
if (process.env.NODE_ENV !== 'production' && typeof warn === 'function') {
245
warn(message, component);
246
} else {
247
console.warn(message);
248
}
249
}
250
```
251
252
### Vue 2.7 App Creation Polyfill
253
254
For Vue 2.7, vue-demi provides a polyfill for Vue 3's `createApp` API.
255
256
```typescript { .api }
257
/**
258
* Create Vue 3 style app instance (Vue 2.7 only)
259
* Polyfill that wraps Vue 2 constructor with Vue 3 app interface
260
*/
261
export function createApp(rootComponent: any, rootProps?: any): App;
262
263
interface App<T = any> {
264
config: VueConstructor['config'];
265
use: VueConstructor['use'];
266
mixin: VueConstructor['mixin'];
267
component: VueConstructor['component'];
268
directive(name: string): Directive | undefined;
269
directive(name: string, directive: Directive): this;
270
provide<T>(key: InjectionKey<T> | string, value: T): this;
271
mount: Vue['$mount'];
272
unmount: Vue['$destroy'];
273
}
274
```
275
276
**Usage Examples (Vue 2.7 only):**
277
278
```typescript
279
import { createApp, isVue2 } from "vue-demi";
280
281
const MyComponent = {
282
template: '<div>{{ message }}</div>',
283
data() {
284
return { message: 'Hello Vue!' };
285
}
286
};
287
288
// Vue 2.7 with createApp polyfill
289
if (isVue2) {
290
const app = createApp(MyComponent);
291
app.provide('theme', 'dark');
292
app.mount('#app');
293
}
294
```