0
# Base Components
1
2
Re-exported components and utilities from vue-class-component and Vue core. These provide the foundational elements for class-based Vue component development and are essential for building components with decorators.
3
4
## Capabilities
5
6
### Component Decorator
7
8
The core class decorator that transforms TypeScript classes into Vue components, enabling the class-based component syntax.
9
10
```typescript { .api }
11
/**
12
* Class decorator that transforms TypeScript classes into Vue components
13
* @param options - Vue component options object (optional)
14
* @returns Decorated Vue component class
15
*/
16
const Component: ComponentDecorator;
17
18
interface ComponentDecorator {
19
<V extends VueClass<Vue>>(target: V): V;
20
<V extends VueClass<Vue>>(options: ComponentOptions<Vue>): (target: V) => V;
21
}
22
23
interface ComponentOptions<V extends Vue> {
24
name?: string;
25
components?: { [key: string]: Component | AsyncComponent };
26
directives?: { [key: string]: DirectiveFunction | DirectiveOptions };
27
filters?: { [key: string]: Function };
28
mixins?: ComponentOptions<Vue>[];
29
extends?: ComponentOptions<Vue>;
30
template?: string;
31
render?(createElement: CreateElement, hack: RenderContext<V>): VNode;
32
renderError?(createElement: CreateElement, err: Error): VNode;
33
staticRenderFns?: (() => VNode)[];
34
beforeCreate?(this: V): void;
35
created?(this: V): void;
36
beforeMount?(this: V): void;
37
mounted?(this: V): void;
38
beforeUpdate?(this: V): void;
39
updated?(this: V): void;
40
activated?(this: V): void;
41
deactivated?(this: V): void;
42
beforeDestroy?(this: V): void;
43
destroyed?(this: V): void;
44
errorCaptured?(this: V, err: Error, instance: Vue, info: string): boolean | void;
45
}
46
```
47
48
**Usage Examples:**
49
50
```typescript
51
import { Vue, Component } from "vue-property-decorator";
52
53
// Basic component
54
@Component
55
export default class BasicComponent extends Vue {
56
message = "Hello World";
57
}
58
59
// Component with options
60
@Component({
61
name: "MyCustomComponent",
62
components: {
63
ChildComponent: () => import("./ChildComponent.vue")
64
},
65
template: `
66
<div>
67
<h1>{{ title }}</h1>
68
<child-component />
69
</div>
70
`
71
})
72
export default class CustomComponent extends Vue {
73
title = "Custom Component";
74
}
75
76
// Component with lifecycle hooks
77
@Component
78
export default class LifecycleComponent extends Vue {
79
data = [];
80
81
created() {
82
console.log("Component created");
83
this.fetchData();
84
}
85
86
mounted() {
87
console.log("Component mounted");
88
}
89
90
beforeDestroy() {
91
console.log("Component will be destroyed");
92
this.cleanup();
93
}
94
95
private async fetchData() {
96
// Fetch data implementation
97
}
98
99
private cleanup() {
100
// Cleanup implementation
101
}
102
}
103
```
104
105
### Vue Base Class
106
107
The core Vue constructor class that provides all Vue instance methods and properties for class-based components.
108
109
```typescript { .api }
110
/**
111
* Vue base class providing all Vue instance methods and properties
112
*/
113
const Vue: VueConstructor;
114
115
interface VueConstructor {
116
new <Data = object, Methods = object, Computed = object, Props = object>(
117
options?: ComponentOptions<Vue, Data, Methods, Computed, Props>
118
): CombinedVueInstance<Vue, Data, Methods, Computed, Props>;
119
120
extend<Data, Methods, Computed, Props>(
121
options?: ComponentOptions<Vue, Data, Methods, Computed, Props>
122
): ExtendedVue<Vue, Data, Methods, Computed, Props>;
123
124
component(id: string): VueConstructor;
125
component<Props>(id: string, definition: Component<any, any, any, Props>): ExtendedVue<Vue, {}, {}, {}, Props>;
126
127
use<T>(plugin: PluginFunction<T>, options?: T): VueConstructor;
128
use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): VueConstructor;
129
130
mixin(mixin: VueConstructor | ComponentOptions<Vue>): VueConstructor;
131
132
directive(id: string): DirectiveOptions;
133
directive(id: string, definition: DirectiveOptions | DirectiveFunction): VueConstructor;
134
135
filter(id: string): Function;
136
filter(id: string, definition: Function): VueConstructor;
137
138
compile(template: string): {
139
render(this: Component): VNode;
140
staticRenderFns: (() => VNode)[];
141
};
142
143
config: VueConfiguration;
144
version: string;
145
}
146
```
147
148
**Usage Examples:**
149
150
```typescript
151
import { Vue, Component } from "vue-property-decorator";
152
153
@Component
154
export default class MyComponent extends Vue {
155
// Vue instance properties and methods are available
156
message = "Hello";
157
158
// Access Vue instance methods
159
updateMessage() {
160
this.$nextTick(() => {
161
console.log("DOM updated");
162
});
163
}
164
165
// Access reactive data methods
166
setData() {
167
this.$set(this.someObject, "newKey", "newValue");
168
}
169
170
// Emit events
171
handleClick() {
172
this.$emit("custom-event", { data: this.message });
173
}
174
175
// Access lifecycle
176
mounted() {
177
console.log("Component element:", this.$el);
178
console.log("Parent component:", this.$parent);
179
console.log("Root component:", this.$root);
180
}
181
}
182
```
183
184
### Mixins Function
185
186
Helper function for creating mixed component classes, enabling composition of multiple component behaviors.
187
188
```typescript { .api }
189
/**
190
* Helper function for creating mixed component classes
191
* @param mixins - Array of Vue classes to mix
192
* @returns Mixed Vue class constructor
193
*/
194
function Mixins(...mixins: VueClass<Vue>[]): VueClass<Vue>;
195
196
type VueClass<V> = {
197
new(...args: any[]): V & Vue;
198
} & typeof Vue;
199
```
200
201
**Usage Examples:**
202
203
```typescript
204
import { Vue, Component, Mixins } from "vue-property-decorator";
205
206
// Define mixin classes
207
@Component
208
class TimestampMixin extends Vue {
209
created() {
210
console.log(`Component created at: ${new Date().toISOString()}`);
211
}
212
213
getTimestamp() {
214
return Date.now();
215
}
216
}
217
218
@Component
219
class ValidationMixin extends Vue {
220
errors: any = {};
221
222
validate(data: any): boolean {
223
// Validation logic
224
return Object.keys(this.errors).length === 0;
225
}
226
227
clearErrors() {
228
this.errors = {};
229
}
230
}
231
232
// Use mixins in component
233
@Component
234
export default class MixedComponent extends Mixins(TimestampMixin, ValidationMixin) {
235
formData = {};
236
237
// Now has access to methods from both mixins
238
handleSubmit() {
239
if (this.validate(this.formData)) {
240
console.log(`Form submitted at: ${this.getTimestamp()}`);
241
}
242
}
243
244
resetForm() {
245
this.formData = {};
246
this.clearErrors(); // From ValidationMixin
247
}
248
}
249
250
// Advanced mixin with generics
251
@Component
252
class DataMixin<T> extends Vue {
253
data: T[] = [];
254
loading = false;
255
256
async fetchData(url: string): Promise<T[]> {
257
this.loading = true;
258
try {
259
const response = await fetch(url);
260
this.data = await response.json();
261
return this.data;
262
} finally {
263
this.loading = false;
264
}
265
}
266
}
267
268
// Use generic mixin
269
interface User {
270
id: number;
271
name: string;
272
email: string;
273
}
274
275
@Component
276
export default class UserList extends Mixins(DataMixin) {
277
async mounted() {
278
await this.fetchData("/api/users");
279
}
280
281
get users(): User[] {
282
return this.data as User[];
283
}
284
}
285
```
286
287
## Advanced Usage Patterns
288
289
### Component Factory Pattern
290
291
```typescript
292
import { Vue, Component } from "vue-property-decorator";
293
294
// Base component with common functionality
295
@Component
296
class BaseFormComponent extends Vue {
297
loading = false;
298
errors: any = {};
299
300
protected async submitForm(data: any): Promise<void> {
301
this.loading = true;
302
this.errors = {};
303
304
try {
305
await this.performSubmit(data);
306
this.$emit("success", data);
307
} catch (error) {
308
this.errors = error.response?.data?.errors || { general: error.message };
309
this.$emit("error", error);
310
} finally {
311
this.loading = false;
312
}
313
}
314
315
protected async performSubmit(data: any): Promise<void> {
316
// Override in subclasses
317
throw new Error("performSubmit must be implemented");
318
}
319
}
320
321
// Specific form implementation
322
@Component
323
export default class UserRegistrationForm extends BaseFormComponent {
324
userData = {
325
name: "",
326
email: "",
327
password: ""
328
};
329
330
protected async performSubmit(data: any): Promise<void> {
331
const response = await fetch("/api/register", {
332
method: "POST",
333
headers: { "Content-Type": "application/json" },
334
body: JSON.stringify(data)
335
});
336
337
if (!response.ok) {
338
throw new Error("Registration failed");
339
}
340
}
341
342
handleSubmit() {
343
this.submitForm(this.userData);
344
}
345
}
346
```
347
348
### Plugin Integration
349
350
```typescript
351
import { Vue, Component } from "vue-property-decorator";
352
353
// Extend Vue with plugin types
354
declare module "vue/types/vue" {
355
interface Vue {
356
$http: {
357
get(url: string): Promise<any>;
358
post(url: string, data: any): Promise<any>;
359
};
360
$notify: {
361
success(message: string): void;
362
error(message: string): void;
363
};
364
}
365
}
366
367
@Component
368
export default class PluginAwareComponent extends Vue {
369
async loadData() {
370
try {
371
const data = await this.$http.get("/api/data");
372
this.$notify.success("Data loaded successfully");
373
return data;
374
} catch (error) {
375
this.$notify.error("Failed to load data");
376
throw error;
377
}
378
}
379
}
380
```
381
382
## Types
383
384
```typescript { .api }
385
interface ComponentOptions<V extends Vue, Data = DefaultData<V>, Methods = DefaultMethods<V>, Computed = DefaultComputed, Props = DefaultProps> {
386
data?: Data;
387
props?: Props;
388
propsData?: object;
389
computed?: Computed;
390
methods?: Methods;
391
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any>>;
392
el?: Element | string;
393
template?: string;
394
render?(createElement: CreateElement, hack: RenderContext<V>): VNode;
395
renderError?(createElement: CreateElement, err: Error): VNode;
396
staticRenderFns?: (() => VNode)[];
397
beforeCreate?(this: V): void;
398
created?(this: V): void;
399
beforeMount?(this: V): void;
400
mounted?(this: V): void;
401
beforeUpdate?(this: V): void;
402
updated?(this: V): void;
403
activated?(this: V): void;
404
deactivated?(this: V): void;
405
beforeDestroy?(this: V): void;
406
destroyed?(this: V): void;
407
errorCaptured?(this: V, err: Error, instance: Vue, info: string): boolean | void;
408
directives?: { [key: string]: DirectiveFunction | DirectiveOptions };
409
components?: { [key: string]: Component | AsyncComponent };
410
transitions?: { [key: string]: object };
411
filters?: { [key: string]: Function };
412
provide?: object | (() => object);
413
inject?: InjectOptions;
414
model?: { prop?: string; event?: string };
415
parent?: Vue;
416
mixins?: (VueConstructor | ComponentOptions<Vue>)[];
417
name?: string;
418
extends?: VueConstructor | ComponentOptions<Vue>;
419
delimiters?: [string, string];
420
comments?: boolean;
421
inheritAttrs?: boolean;
422
}
423
424
type VueClass<V> = { new(...args: any[]): V & Vue } & typeof Vue;
425
type ComponentDecorator = <V extends VueClass<Vue>>(target: V) => V;
426
```