0
# Component System
1
2
Vue's component system provides a declarative way to build reactive user interfaces through reusable components with lifecycle management, props, and composition API integration.
3
4
## Capabilities
5
6
### Component Definition
7
8
Define components using the composition API or options API with full TypeScript support.
9
10
```typescript { .api }
11
/**
12
* Defines a component with setup function
13
* @param setup - Setup function with props and context
14
* @param options - Additional component options
15
* @returns Component definition
16
*/
17
function defineComponent<Props, RawBindings = object>(
18
setup: (props: Props, ctx: SetupContext) => RawBindings | RenderFunction
19
): DefineComponent<Props, RawBindings>;
20
21
/**
22
* Defines a component with options object
23
* @param options - Component options including data, methods, computed, etc.
24
* @returns Component definition
25
*/
26
function defineComponent<
27
Props = {},
28
RawBindings = {},
29
D = {},
30
C extends ComputedOptions = {},
31
M extends MethodOptions = {}
32
>(options: ComponentOptionsWithoutProps<Props, RawBindings, D, C, M>): DefineComponent<Props, RawBindings, D, C, M>;
33
34
/**
35
* Defines an async component with loader function
36
* @param loader - Function that returns a Promise resolving to component
37
* @returns Async component
38
*/
39
function defineAsyncComponent<T extends Component = Component>(
40
loader: AsyncComponentLoader<T>
41
): T;
42
43
/**
44
* Defines an async component with options
45
* @param options - Async component configuration
46
* @returns Async component
47
*/
48
function defineAsyncComponent<T extends Component = Component>(
49
options: AsyncComponentOptions<T>
50
): T;
51
```
52
53
**Usage Examples:**
54
55
```typescript
56
import { defineComponent, defineAsyncComponent, ref, computed } from "@vue/runtime-core";
57
58
// Composition API component
59
const MyComponent = defineComponent({
60
props: {
61
message: String,
62
count: Number
63
},
64
setup(props, { emit, expose }) {
65
const localCount = ref(props.count || 0);
66
const doubled = computed(() => localCount.value * 2);
67
68
const increment = () => {
69
localCount.value++;
70
emit('update:count', localCount.value);
71
};
72
73
// Expose methods to parent
74
expose({ increment });
75
76
return {
77
localCount,
78
doubled,
79
increment
80
};
81
}
82
});
83
84
// Options API component
85
const OptionsComponent = defineComponent({
86
props: ['title'],
87
data() {
88
return {
89
count: 0
90
};
91
},
92
computed: {
93
uppercaseTitle() {
94
return this.title?.toUpperCase();
95
}
96
},
97
methods: {
98
increment() {
99
this.count++;
100
}
101
}
102
});
103
104
// Async component with loader
105
const AsyncComp = defineAsyncComponent(() => import('./HeavyComponent.vue'));
106
107
// Async component with options
108
const AsyncCompWithOptions = defineAsyncComponent({
109
loader: () => import('./HeavyComponent.vue'),
110
loadingComponent: LoadingComponent,
111
errorComponent: ErrorComponent,
112
delay: 200,
113
timeout: 3000
114
});
115
```
116
117
### Component Instance Management
118
119
Access and manage component instances with their internal state and lifecycle.
120
121
```typescript { .api }
122
/**
123
* Gets the current component instance (only available during setup)
124
* @returns Current component instance or null
125
*/
126
function getCurrentInstance(): ComponentInternalInstance | null;
127
128
/**
129
* Registers a runtime compiler for template compilation
130
* @param compile - Compiler function
131
*/
132
function registerRuntimeCompiler(compile: any): void;
133
134
/**
135
* Checks if running in runtime-only mode
136
* @returns True if runtime-only, false if full build
137
*/
138
function isRuntimeOnly(): boolean;
139
```
140
141
**Usage Examples:**
142
143
```typescript
144
import { defineComponent, getCurrentInstance, onMounted } from "@vue/runtime-core";
145
146
const MyComponent = defineComponent({
147
setup() {
148
const instance = getCurrentInstance();
149
150
onMounted(() => {
151
if (instance) {
152
console.log('Component UID:', instance.uid);
153
console.log('Parent:', instance.parent);
154
console.log('VNode:', instance.vnode);
155
}
156
});
157
158
return {};
159
}
160
});
161
```
162
163
### Setup Context & Helpers
164
165
Access component context and utility functions within the setup function.
166
167
```typescript { .api }
168
/**
169
* Gets setup context slots (only available during setup)
170
* @returns Component slots object
171
*/
172
function useSlots(): Slots;
173
174
/**
175
* Gets setup context attrs (only available during setup)
176
* @returns Component attrs object
177
*/
178
function useAttrs(): Data;
179
```
180
181
**Usage Examples:**
182
183
```typescript
184
import { defineComponent, useSlots, useAttrs } from "@vue/runtime-core";
185
186
const WrapperComponent = defineComponent({
187
setup() {
188
const slots = useSlots();
189
const attrs = useAttrs();
190
191
console.log('Available slots:', Object.keys(slots));
192
console.log('Component attrs:', attrs);
193
194
return {
195
slots,
196
attrs
197
};
198
}
199
});
200
```
201
202
### Script Setup Macros
203
204
Compile-time macros for `<script setup>` syntax (runtime representations for typing).
205
206
```typescript { .api }
207
/**
208
* Declares component props (compile-time macro)
209
* @returns Props type
210
*/
211
function defineProps<T = {}>(): T;
212
213
/**
214
* Declares component emits (compile-time macro)
215
* @returns Emit function
216
*/
217
function defineEmits<T extends EmitsOptions = {}>(): EmitFn<T>;
218
219
/**
220
* Declares exposed properties and methods (compile-time macro)
221
* @param exposed - Object containing exposed properties
222
*/
223
function defineExpose<T extends Record<string, any>>(exposed?: T): void;
224
225
/**
226
* Declares additional component options (compile-time macro)
227
* @param options - Component options
228
*/
229
function defineOptions<T extends Partial<ComponentOptions>>(options?: T): void;
230
231
/**
232
* Declares slot types (compile-time macro)
233
* @returns Slots type
234
*/
235
function defineSlots<S extends Record<string, any> = Record<string, any>>(): S;
236
237
/**
238
* Declares v-model props (compile-time macro)
239
* @returns Model ref
240
*/
241
function defineModel<T>(): ModelRef<T>;
242
243
/**
244
* Provides default values for props (compile-time macro)
245
* @param props - Props object
246
* @param defaults - Default values
247
* @returns Props with defaults applied
248
*/
249
function withDefaults<T>(props: T, defaults: Partial<T>): T;
250
```
251
252
**Usage Examples:**
253
254
```typescript
255
import { defineComponent, defineProps, defineEmits, defineExpose } from "@vue/runtime-core";
256
257
// These are typically used in <script setup> but shown here for API reference
258
const ScriptSetupComponent = defineComponent({
259
setup() {
260
// These macros are compile-time only in actual <script setup>
261
const props = defineProps<{
262
message: string;
263
count?: number;
264
}>();
265
266
const emit = defineEmits<{
267
'update:count': [value: number];
268
'click': [event: MouseEvent];
269
}>();
270
271
const increment = () => {
272
const newCount = (props.count || 0) + 1;
273
emit('update:count', newCount);
274
};
275
276
defineExpose({
277
increment
278
});
279
280
return {
281
increment
282
};
283
}
284
});
285
```
286
287
### Internal Setup Helpers
288
289
Internal helper functions for advanced component composition patterns.
290
291
```typescript { .api }
292
/**
293
* Merges prop defaults with props (internal)
294
* @param props - Props object
295
* @param defaults - Default values
296
* @returns Merged props
297
*/
298
function mergeDefaults<T>(props: T, defaults: Partial<T>): T;
299
300
/**
301
* Merges model declarations (internal)
302
* @param props - Props object
303
* @param models - Model declarations
304
* @returns Merged props with models
305
*/
306
function mergeModels<T>(props: T, models: Record<string, any>): T;
307
308
/**
309
* Creates a rest proxy for props destructuring (internal)
310
* @param props - Props object
311
* @param excludedKeys - Keys to exclude from rest
312
* @returns Rest proxy
313
*/
314
function createPropsRestProxy<T extends Record<string, any>>(
315
props: T,
316
excludedKeys: string[]
317
): Omit<T, keyof typeof excludedKeys>;
318
319
/**
320
* Preserves instance context over async/await (internal)
321
* @param getAwaitable - Function returning awaitable
322
* @returns Awaitable with preserved context
323
*/
324
function withAsyncContext<T>(getAwaitable: () => T): T;
325
```
326
327
## Types
328
329
```typescript { .api }
330
interface ComponentInternalInstance {
331
uid: number;
332
vnode: VNode;
333
type: ConcreteComponent;
334
parent: ComponentInternalInstance | null;
335
root: ComponentInternalInstance;
336
appContext: AppContext;
337
338
// State
339
data: Data;
340
props: Data;
341
attrs: Data;
342
slots: InternalSlots;
343
refs: Data;
344
emit: EmitFn;
345
346
// Lifecycle
347
isMounted: boolean;
348
isUnmounted: boolean;
349
isDeactivated: boolean;
350
351
// Setup
352
setupState: Data;
353
setupContext: SetupContext | null;
354
355
// Render
356
render: InternalRenderFunction | null;
357
proxy: ComponentPublicInstance | null;
358
exposed: Record<string, any> | null;
359
360
// Suspense
361
suspense: SuspenseBoundary | null;
362
suspenseId: number;
363
364
// SSR
365
ssrContext: object | null;
366
}
367
368
interface SetupContext<E = EmitsOptions> {
369
attrs: Data;
370
slots: Slots;
371
emit: EmitFn<E>;
372
expose: (exposed?: Record<string, any>) => void;
373
}
374
375
type DefineComponent<
376
PropsOrPropOptions = {},
377
RawBindings = {},
378
D = {},
379
C extends ComputedOptions = ComputedOptions,
380
M extends MethodOptions = MethodOptions,
381
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
382
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
383
E extends EmitsOptions = {},
384
EE extends string = string,
385
PP = PublicProps,
386
Props = Readonly<PropsOrPropOptions>,
387
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>
388
> = ComponentPublicInstanceConstructor<
389
CreateComponentPublicInstance<
390
Props,
391
RawBindings,
392
D,
393
C,
394
M,
395
Mixin,
396
Extends,
397
E,
398
PP & Props,
399
Defaults,
400
true
401
> &
402
Props
403
> &
404
ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE, Defaults> &
405
PP;
406
407
interface AsyncComponentLoader<T = any> {
408
(): Promise<T>;
409
}
410
411
interface AsyncComponentOptions<T = any> {
412
loader: AsyncComponentLoader<T>;
413
loadingComponent?: Component;
414
errorComponent?: Component;
415
delay?: number;
416
timeout?: number;
417
suspensible?: boolean;
418
onError?: (
419
error: Error,
420
retry: () => void,
421
fail: () => void,
422
attempts: number
423
) => any;
424
}
425
426
interface ComponentOptions<
427
V = {},
428
D = {},
429
C extends ComputedOptions = {},
430
M extends MethodOptions = {},
431
E extends EmitsOptions = {},
432
Props = {}
433
> {
434
// Data
435
data?: (this: V & Props) => D;
436
props?: ComponentPropsOptions<Props>;
437
propsData?: Partial<Props>; // For 2.x compat only
438
439
// DOM
440
el?: string | Element;
441
template?: string;
442
render?: Function;
443
renderTracked?: DebuggerHook;
444
renderTriggered?: DebuggerHook;
445
446
// Lifecycle
447
beforeCreate?(): void;
448
created?(): void;
449
beforeMount?(): void;
450
mounted?(): void;
451
beforeUpdate?(): void;
452
updated?(): void;
453
activated?(): void;
454
deactivated?(): void;
455
beforeDestroy?(): void;
456
beforeUnmount?(): void;
457
destroyed?(): void;
458
unmounted?(): void;
459
renderError?: (e: Error, instance: ComponentPublicInstance, info: string) => void;
460
errorCaptured?: ErrorCapturedHook;
461
462
// Assets
463
directives?: Record<string, Directive>;
464
components?: Record<string, Component>;
465
466
// Composition
467
mixins?: ComponentOptionsMixin[];
468
extends?: ComponentOptionsMixin;
469
470
// Other
471
name?: string;
472
inheritAttrs?: boolean;
473
emits?: E;
474
expose?: string[];
475
serverPrefetch?(): void | Promise<any>;
476
}
477
478
interface ModelRef<T> extends Ref<T> {
479
readonly [ModelRefMarkerSymbol]: true;
480
}
481
482
type EmitFn<
483
Options = ObjectEmitsOptions,
484
Event extends keyof Options = keyof Options
485
> = Options extends Array<infer V>
486
? (event: V, ...args: any[]) => void
487
: {} extends Options // if the emit is empty object (usually the default value for emit) should be converted to function
488
? (event: string, ...args: any[]) => void
489
: UnionToIntersection<
490
{
491
[key in Event]: Options[key] extends (...args: infer Args) => any
492
? (event: key, ...args: Args) => void
493
: (event: key, ...args: any[]) => void;
494
}[Event]
495
>;
496
497
interface Slots {
498
[name: string]: Slot | undefined;
499
}
500
501
type Slot<T extends any = any> = (
502
...args: IfAny<T, any[], [T] | (T extends undefined ? [] : never)>
503
) => VNode[];
504
```