vue-clazz-decorator
v0.1.0
Published
Write Vue 3 components with Class + Decorators, featuring ViewModel/View separation, metadata system, and reactive model layer.
Maintainers
Readme
vue-clazz-decorator 让你在 Vue 3 中使用 Class + 装饰器 的风格来写组件。
特色
- 通过类的方式来写 Vue 组件
- 方便地复用模板和逻辑
- 保证自定义类型的纯净
- 支持多种装饰器编译方式
- 兼容 reflect-metadata API
- 完整的数据模型层:序列化/反序列化/类型转换
如果你喜欢 vue-class-component 或 vue-property-decorator, 那么请试试这个项目吧!
创建组件
这个库的核心思想是 组件 = 模板 + 业务逻辑。这是 createComponent 设计的体现,避开 Vue 3 不能用 class 组件的同时,顺便能复用模板和逻辑。
@ViewModel
export class CounterViewModel {
@State
public count = 0;
@Computed
public get doubleCount() {
return this.count * 2;
}
public increment() {
this.count++;
}
}
export function CounterView(props: CounterViewModel) {
return <div>
<p>Count: {props.count}</p>
<button onClick={props.increment}>+1</button>
</div>;
}
export const Counter = createComponent(CounterView, CounterViewModel);组件生命周期
使用注解声明生命周期方法,不强制固定方法名,一个钩子可以绑定多个方法,保证类的纯净。
@ViewModel
export class FooViewModel {
@OnDidCreate
protected init() {
console.log("ViewModel created");
}
@OnDidMount
protected xxxx() {
console.log("componentDidMount");
}
@OnDidMount
protected yyyy() {
console.log("componentDidMount again");
}
}
export function FooView(props: FooViewModel) {
return <div></div>;
}
export const Foo = createComponent(FooView, FooViewModel);组件逻辑复用
业务逻辑自动就包在命名空间里,非常易于管理。
@ViewModel
export class FooViewModel {
}
@ViewModel
export class BarViewModel {
public foo1 = use(FooViewModel);
public foo2 = use(FooViewModel);
}
export function BarView(props: BarViewModel) {
return <div></div>;
}
export const Bar = createComponent(BarView, BarViewModel);模型层声明
用 @Model 标记数据模型类,结合元数据描述字段含义,再通过 reactive() 将普通数据转为响应式实例,同时保留类型信息。
@Model
export class UserBo {
@metadata('label', "用户ID")
public id: string;
@metadata('label', "用户名")
public name: string;
}
var user = reactive({
id: "admin",
name: "超级管理员",
}, UserBo);如何写一个注解
库内置的metadata函数可以便捷地帮助我们创建一个注解。
// 定义一个注解
function Label(text: string) {
return metadata('label', text);
}
// 使用
@Model
export class UserBo {
@Label("用户ID")
public id: string;
@Label("用户名")
public name: string;
}
// 获取元数据
getMetadataValues(UserBo);
// { id: { label: "用户ID"}, name: { label: "用户名" } }支持的装饰器编译方式
项目支持多种方式,并可以混合使用。
experimentalDecorators: false+useDefineForClassFields: true以下简称 proposalexperimentalDecorators: true+useDefineForClassFields: false以下简称 experimentalexperimentalDecorators: true+useDefineForClassFields: false+emitDecoratorMetadata: true以下简称 metadata
| 编译方式 | proposal | experimental | metadata | | --- | --- | --- | --- | | typescript | ✅ 支持 | ✅ 支持 | ✅ 支持 | | babel | ✅ 支持 | ✅ 支持 | ✅ 支持 |
文档导航
- 新手上路 — 环境配置、第一个组件、装饰器编译
- 组件开发 — 如何用类和装饰器开发 Vue 组件
- 元数据操作 — 如何对类的元数据进行增删改查
- 数据模型 — 数据类型转化、JSON 序列化
- 进阶用法 — 构建方式、自定义装饰器
- API 参考 — 函数签名与参数速查
- 常见问题 — FAQ
功能清单
| 分类 | API | | --- | --- | | 组件创建 | createComponent use useChildren | | 类装饰器 | @ViewModel @Model | | 数据装饰器 | @State @Reactive @Computed @Ref @Watch | | 组件通信装饰器 | @Prop @Emit @ModelValue @Provide @Inject | | 生命周期装饰器 | @OnDidCreate @OnWillMount @OnDidMount @OnWillUpdate @OnDidUpdate @OnWillUnmount @OnDidUnmount @OnDidCatch | | JSON 序列化装饰器 | @JsonProperty @JsonExpose @JsonIgnore @JsonSerialize @JsonDeserialize @JsonFormat | | 数据类型装饰器 | @Type ArrayType ReactiveArrayType @From | | 元数据操作函数 | metadata defineMetadata defineClassMetadata defineFieldMetadata getClassMetadataValues getFieldMetadataValues | | 元数据查询函数 | getMetadata getOwnMetadata getMetadataKeys getOwnMetadataKeys hasMetadata hasOwnMetadata deleteMetadata | | 兼容 reflect-metadata 函数 | metadata hasOwnMetadata getOwnMetadataKeys getOwnMetadata getMetadata deleteMetadata defineMetadata | | 模型实例化函数 | reactive normalize hydrate | | 其他导出 | nextTick state computed |
