Vue3 Class 组件开发语法
基于 vue-facing-decorator 库,在 Vue3 中使用 class 语法和装饰器开发组件,支持面向对象特性(继承、接口)。
执行步骤
当调用此 Skill 时,按以下步骤创建项目并初始化:
步骤 1:创建 Vite + Vue3 + TypeScript 项目
# 创建项目,使用 Vue + TypeScript 模板
npm create vite@latest . -- --template vue-ts
# 安装核心依赖
npm install vue-facing-decorator
步骤 2:配置 tsconfig.app.json
在 tsconfig.app.json 的 compilerOptions 中添加两项配置:
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": true
}
}
步骤 3:配置 vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": resolve(__dirname, "src"),
"@com": resolve(__dirname, "src/com"),
},
},
});
步骤 4:创建目录结构
mkdir -p src/components
步骤 5:创建入口 HTML
创建 src/index.html:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue3 Class 示例</title>
</head>
<body>
<div id="app"></div>
<script type="module" lang="ts">
import { createApp } from "vue";
import App from "./index.vue";
createApp(App).mount("#app");
</script>
</body>
</html>
步骤 6:创建基础类
创建 src/index.ts:
import { Vue } from "vue-facing-decorator";
export default class Index extends Vue {
public title: string = "Vue3 Class 组件示例";
log(msg: string) {
console.log(msg);
}
}
步骤 7:创建根组件
创建 src/index.vue:
<template>
<div>
<h1>{{ title }}</h1>
<Counter :start-value="10" @reset="handleReset" />
</div>
</template>
<script lang="ts">
import { Component, toNative } from 'vue-facing-decorator';
import Index from './index';
import Counter from './components/Counter.vue';
@Component({
components: {
Counter
}
})
class App extends Index {
handleReset(val: number) {
this.log('已重置为:' + val);
}
}
export default toNative(App);
</script>
步骤 8:创建示例组件
创建 src/components/Counter.vue:
<template>
<div>
<p>计数: {{ count }}</p>
<p>加倍: {{ doubleCount }}</p>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="reset">重置</button>
</div>
</template>
<script lang="ts">
import { Component, Prop, Watch, Emit, Vue, toNative } from 'vue-facing-decorator';
@Component
class Counter extends Vue {
@Prop({ default: 0 }) startValue: number;
count: number = 0;
get doubleCount() {
return this.count * 2;
}
mounted() {
this.count = this.startValue;
}
@Watch("count")
onCountChange(newVal: number, oldVal: number) {
console.log(`count 从 ${oldVal} 变为 ${newVal}`);
}
increment() {
this.count++;
}
decrement() {
this.count--;
}
reset() {
this.count = 0;
this.onReset();
}
@Emit("reset")
onReset() {
return this.count;
}
}
export default toNative(Counter);
</script>
步骤 9:验证项目
npm run dev
访问终端输出的地址,页面应显示一个计数器和操作按钮,说明 Vue3 class 组件已成功运行。
最终项目结构
项目根目录/
├── vite.config.ts
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── package.json
├── src/
│ ├── index.html # 入口 HTML
│ ├── index.ts # 基础类
│ ├── index.vue # 根组件(class 写法)
│ └── components/
│ └── Counter.vue # 示例组件(class 写法)
语法参考
1. 组件定义
import { Component, Vue, toNative } from 'vue-facing-decorator';
@Component({
components: {}
})
class MyComponent extends Vue {
// 组件逻辑
}
export default toNative(MyComponent);
2. 属性传参 (@Prop)
import { Component, Prop, Vue, toNative } from 'vue-facing-decorator';
@Component
class MyComponent extends Vue {
@Prop title: string;
@Prop({ default: false }) visible: boolean;
}
3. 监听数据变化 (@Watch)
import { Component, Watch, Vue, toNative } from 'vue-facing-decorator';
@Component
class MyComponent extends Vue {
@Watch("someProperty", { deep: true })
onSomePropertyChange(newVal: any, oldVal: any) {
// 处理变化
}
}
4. 触发事件 (@Emit)
import { Component, Emit, Vue, toNative } from 'vue-facing-decorator';
@Component
class MyComponent extends Vue {
@Emit("close")
handleClose() {
return false;
}
}
5. 计算属性 (getter)
@Component
class MyComponent extends Vue {
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
6. 生命周期方法
@Component
class MyComponent extends Vue {
async mounted() {
this.initData();
}
beforeUnmount() {
// 清理
}
}
面向对象特性
继承
组件类可以继承其他类,实现代码复用:
// 父类
@Component
class BaseComponent extends Vue {
public title: string = "";
log(msg: string) {
console.log(msg);
}
}
// 子类继承父类
@Component
class ChildComponent extends BaseComponent {
async mounted() {
this.log(this.title); // 调用父类方法
}
}
export default toNative(ChildComponent);
接口实现
export interface IControl {
init(): void;
}
@Component
class MyComponent extends Vue implements IControl {
init() {
// 实现接口方法
}
}
export default toNative(MyComponent);
注意事项
- 组件文件必须添加
export default toNative(ComponentClass)导出 @Component装饰器必须放在类声明之前- 使用
@Prop定义传入参数,@Watch监听数据变化,@Emit触发事件 - 组件类需要继承
Vue(从vue-facing-decorator导入) - 在
tsconfig.app.json中必须开启experimentalDecorators和useDefineForClassFields