1.类的基础知识
-
创建类class Person{ }:属性,构造器constructor,方法
-
创建类实例const n1=new Person('张三'):使用属性n1.name,使用方法n1.speak()
-
继承class Student extends Person{}:如果属性和父类一致可以不写构造器,属性和父类不一致需要重写构造器,构造器中用super(```)继承父类属性,重写父类方法:重写一份即可override speak(){}
2.属性修饰符
-
public:类内部、子类、类外部都可访问
-
protected:类内部、子类可访问
-
private:类内部可访问
-
readonly:只读属性,可以和public或protected或private混用,用空格隔开

属性的简写方式

3.抽象类与接口(interface)对比
| 特性 | 接口(Interface) | 抽象类(Abstract Class) |
|---|---|---|
| 核心作用 | 定义 "结构契约"(属性 / 方法的类型约束) | 定义 "模板 + 逻辑"(约束 + 共性逻辑复用) |
| 具体实现 | 无(仅声明,不写方法体) | 有(可包含完整方法、属性初始化) |
| 继承 / 实现方式 | 类用 implements 实现(可多实现) |
类用 extends 继承(仅单继承) |
| 访问修饰符 | 仅 public(默认,不能加 private/protected) |
支持 public/private/protected(控制访问权限) |
| Vue3 适用场景 | 1. 定义组件 Props/Emits 类型;2. 定义接口返回数据结构;3. 约束组件必须实现的方法(无逻辑) | 1. 封装有固定流程的业务逻辑(如表单提交);2. 复用组件共性逻辑(如状态切换);3. 强制子类遵循规则 + 复用代码 |
| 编译产物 | 无(TS 编译后消失,仅类型检查) | 有(编译为普通类,存在运行时) |
4.vue3中interface的实现(约束)
接口的核心是定义结构,在vue3中props,接口数据,组件通信中高频使用。
4.1定义组件props/emits类型
Vue3 中用 interface 约束 Props 结构,让类型检查更严格,替代 PropType 的繁琐写法。
javascript
<!-- components/UserCard.vue -->
<template>
<div class="user-card">
<h3>{{ user.name }}</h3>
<p>{{ user.age }} 岁</p>
<button @click="handleEdit">编辑</button>
</div>
</template>
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
// 1. 定义 User 结构契约
interface User {
id: number;
name: string;
age: number;
avatar?: string; // 可选属性
}
// 2. 用接口约束 Props(比 PropType 更简洁)
const props = defineProps<{
user: User; // 直接使用接口作为类型
isEditable: boolean;
}>();
// 3. 用接口约束 Emits(替代数组写法,支持类型检查)
interface Emits {
(e: 'edit', userId: number): void; // 事件名 + 参数类型
}
const emit = defineEmits<Emits>();
// 触发事件时,TS 会校验参数类型
const handleEdit = () => {
emit('edit', props.user.id); // 正确:参数是 number
// emit('edit', '123'); // 报错:参数必须是 number
};
</script>
4.2 定义接口返回数据结构
约定后端返回数据的格式,避免类型混乱。
javascript
// api/types.ts
// 定义接口返回数据的结构契约
interface LoginResponse {
code: 200 | 500;
msg: string;
data: {
token: string;
userInfo: {
id: number;
name: string;
};
};
}
// api/login.ts
import axios from 'axios';
// 请求函数用接口约束返回值类型
export const login = async (params: { username: string; password: string }): Promise<LoginResponse> => {
const res = await axios.post('/api/login', params);
return res.data; // TS 会校验返回数据是否符合 LoginResponse 结构
};
// 组件中使用
const handleLogin = async () => {
const result = await login({ username: 'admin', password: '123' });
console.log(result.data.token); // 自动提示属性,类型安全
};
5.vue3抽象类(约束+复用)
抽象类的核心约束子类结构,提供复用逻辑,常用的是表单提交,状态切换。
5.1表单提交流程(约束+复用逻辑)
多个表单登录注册,都有验证->提交->错误处理的固定流程,仅验证规则和接口的不同。
javascript
// abstract/BaseForm.ts
// 抽象类:封装固定流程 + 共性逻辑
abstract class BaseForm<T> {
// 固定提交流程(模板方法)
async submit(formData: T): Promise<void> {
try {
this.validate(formData); // 步骤1:验证(子类实现)
const data = this.formatData(formData); // 步骤2:格式化(默认实现,可重写)
const result = await this.request(data); // 步骤3:请求(子类实现)
this.onSuccess(result); // 步骤4:成功处理(子类实现)
} catch (err) {
this.onError(err as Error); // 共性错误处理(默认实现)
}
}
// 抽象方法:必须实现(个性化验证规则)
protected abstract validate(formData: T): void;
// 具体方法:可复用(默认不格式化)
protected formatData(formData: T): T {
return formData;
}
// 抽象方法:必须实现(个性化接口)
protected abstract request(data: T): Promise<any>;
// 抽象方法:必须实现(个性化成功处理)
protected abstract onSuccess(result: any): void;
// 具体方法:可复用(统一错误提示)
protected onError(error: Error): void {
console.error('提交失败:', error.message);
// 可集成 Vue3 提示组件(如 ElMessage)
}
}
// 子类:登录表单(实现抽象方法,复用流程)
class LoginForm extends BaseForm<{ username: string; password: string }> {
protected validate(formData: { username: string; password: string }): void {
if (!formData.username) throw new Error('用户名不能为空');
}
protected async request(data: { username: string; password: string }) {
return axios.post('/api/login', data); // 登录接口
}
protected onSuccess(result: any) {
console.log('登录成功,token:', result.data.token);
}
}
// Vue 组件中使用
<script setup lang="ts">
import { ref } from 'vue';
const formData = ref({ username: '', password: '' });
const loginForm = new LoginForm();
const handleSubmit = () => {
loginForm.submit(formData.value); // 直接调用,复用流程
};
</script>
5.2接口与抽象类配合使用
接口定义:数据接口,最小锲约,抽象类实现逻辑复用,子类专注个性化设置。
带权限的表单提交
javascript
// 1. 接口:定义"权限信息"的结构契约
interface AuthInfo {
token: string;
role: 'admin' | 'user';
}
// 2. 接口:定义"表单数据"的最小契约(所有表单都要有 userId)
interface FormWithAuth {
userId: number;
}
// 3. 抽象类:复用"带权限的请求逻辑"(依赖接口约束)
abstract class AuthForm<T extends FormWithAuth> {
constructor(protected auth: AuthInfo) {} // 接收权限信息
// 共性逻辑:给请求添加权限头
protected getRequestHeaders() {
return {
Authorization: `Bearer ${this.auth.token}`,
'X-Role': this.auth.role,
};
}
// 抽象方法:约束子类必须实现提交逻辑
abstract submit(formData: T): Promise<void>;
}
// 4. 子类:订单表单(实现抽象方法,遵循接口约束)
class OrderForm extends AuthForm<{ userId: number; orderNo: string }> {
async submit(formData: { userId: number; orderNo: string }) {
// 复用抽象类的权限头
const headers = this.getRequestHeaders();
// 提交请求(formData 遵循 FormWithAuth 接口,必须有 userId)
await axios.post('/api/order/submit', formData, { headers });
}
}
// Vue 组件中使用
<script setup lang="ts">
// 模拟权限信息(实际从缓存获取)
const authInfo: AuthInfo = { token: 'xxx', role: 'admin' };
const orderForm = new OrderForm(authInfo);
// 表单数据(必须包含 userId,否则 TS 报错)
const formData = ref({ userId: 1, orderNo: 'OD123456' });
const handleSubmit = () => {
orderForm.submit(formData.value);
};
</script>
-
接口
AuthInfo和FormWithAuth定义数据结构,保证类型安全; -
抽象类
AuthForm复用 "权限头生成" 的共性逻辑; -
子类
OrderForm只需关注订单提交的个性化逻辑,无需重复处理权限
| 需求场景 | 选择工具 |
|---|---|
| 定义 Props/Emits 类型、接口返回数据结构 | 接口(Interface) |
| 仅约束组件 / 类必须实现的方法(无逻辑) | 接口(Interface) |
| 复用共性逻辑(如固定流程、公共方法) | 抽象类(Abstract Class) |
| 既需要约束结构,又需要复用逻辑 | 接口 + 抽象类(配合使用) |
| 希望多实现(一个类遵循多个契约) | 接口(多 implements) |