Vue typescript class and decorator based component system with support for ES class inheritance and Vue 3 composition API integration.
npx @tessl/cli install tessl/npm-vue-facing-decorator@4.0.0Vue Facing Decorator is a comprehensive Vue 3 class-based component system with TypeScript decorators, designed to replicate the functionality of vue-class-component and vue-property-decorator for Vue 3. It supports both stage 2 and stage 3 decorators, offers ES class inheritance with Vue extends and mixins, and transforms ES classes to Vue Option API according to specifications.
npm install vue-facing-decoratorvue@^3.0.0facing-metadata@^2.0.0import { Component, Setup, Ref, Watch, Prop, Emit, VModel } from "vue-facing-decorator";Additional imports:
import { Provide, Inject, Vanilla, Hook, createDecorator, TSX } from "vue-facing-decorator";Base classes and utilities:
import { ComponentBase, Base, mixins, toNative } from "vue-facing-decorator";For CommonJS:
const { Component, Setup, Ref, Watch, Prop, Emit, VModel } = require("vue-facing-decorator");import { Component, Setup, Ref, Watch, Prop, Emit } from "vue-facing-decorator";
import { ref } from "vue";
@Component
class MyComponent {
// Props with validation
@Prop({ type: String, required: true })
title!: string;
@Prop({ type: Number, default: 0 })
count!: number;
// Reactive data using setup
@Setup(() => ref("Hello World"))
message!: string;
// Template refs
@Ref()
inputElement!: HTMLInputElement;
// Watchers
@Watch("count")
onCountChange(newVal: number, oldVal: number) {
console.log(`Count changed from ${oldVal} to ${newVal}`);
}
// Event emitters
@Emit("update")
emitUpdate() {
return { message: this.message, count: this.count };
}
// Lifecycle hooks
mounted() {
this.inputElement?.focus();
}
// Methods
increment() {
this.count++;
this.emitUpdate();
}
}
export default toNative(MyComponent);Vue Facing Decorator is built around several key components:
@Component transforms ES classes into Vue components with proper option mappingBase/Vue provides inheritance foundation for component classesmixins() function enables composition of multiple component classesFoundation classes and decorators for creating Vue components from TypeScript classes.
function Component(options?: ComponentOption): ClassDecorator;
const ComponentBase: (options?: ComponentOption) => ClassDecorator;
class Base { }
const Vue: typeof Base;
function toNative<T extends VueCons>(cons: T): T;Decorators for reactive properties, props, template references, and data binding.
function Setup(setupFunction: OptionSetupFunction): PropertyDecorator;
function Ref(key?: string): PropertyDecorator;
function Prop(config?: PropsConfig): PropertyDecorator;
function VModel(config?: VModelConfig): PropertyDecorator;
const Model: typeof VModel;
function Vanilla(): PropertyDecorator;Decorators for watchers, event emitters, dependency injection, and lifecycle hooks.
function Watch(key: string, options?: WatchOptions): MethodDecorator;
function Emit(eventName?: string): MethodDecorator;
function Provide(key?: string): PropertyDecorator;
function Inject(config?: InjectConfig): PropertyDecorator;
function Hook(): MethodDecorator;Method and Lifecycle Decorators
Mixins, custom decorators, TypeScript JSX support, and utility functions.
function mixins<T extends VueCons[]>(...conses: T): MixedClass<T>;
function createDecorator(creator: Creator, options?: { preserve?: boolean }): PropertyDecorator;
function TSX<Properties, Events, IT>(): <C extends VueCons>(cons: C) => VueCons<InstanceType<C>, MergeIdentityType<IT, InstanceType<C>[typeof IdentitySymbol]>>;interface ComponentOption {
name?: string;
emits?: string[];
provide?: Record<string, any> | Function;
components?: Record<string, any>;
directives?: Record<string, any>;
inheritAttrs?: boolean;
expose?: string[];
render?: Function;
template?: string;
mixins?: any[];
setup?: ComponentSetupFunction;
methods?: MethodOptions;
modifier?: (raw: any) => any;
options?: ComponentCustomOptions & Record<string, any>;
}
interface PropsConfig {
type?: any;
required?: boolean;
default?: any;
validator?(value: any): boolean;
}
interface WatchOptions {
flush?: 'post';
deep?: boolean;
immediate?: boolean;
}
interface InjectConfig {
from?: string | symbol | Symbol | InjectionKey<any>;
default?: any;
}
interface VModelConfig extends PropsConfig {
name?: string;
}
type VueCons<RawInstance = Identity, IT = { props: {}, events: {} }> = {
new(): ComponentPublicInstance & Identity<IT> & Omit<RawInstance, typeof IdentitySymbol>;
};interface HookBeforeCreate { beforeCreate(): void; }
interface HookCreated { created(): void; }
interface HookBeforeMount { beforeMount(): void; }
interface HookMounted { mounted(): void; }
interface HookBeforeUpdate { beforeUpdate(): void; }
interface HookUpdated { updated(): void; }
interface HookActivated { activated(): void; }
interface HookDeactivated { deactivated(): void; }
interface HookBeforeDestroy { beforeDestroy(): void; }
interface HookBeforeUnmount { beforeUnmount(): void; }
interface HookDestroyed { destroyed(): void; }
interface HookUnmounted { unmounted(): void; }
interface HookRenderTracked { renderTracked(): void; }
interface HookRenderTriggered { renderTriggered(): void; }
interface HookErrorCaptured { errorCaptured(): void; }
interface HookServerPrefetch { serverPrefetch(): void; }
interface HookRender { render(): void; }