ts-属性修饰符,接口(约束数据结构),抽象类(约束与复用逻辑)

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>
  • 接口 AuthInfoFormWithAuth 定义数据结构,保证类型安全;

  • 抽象类 AuthForm 复用 "权限头生成" 的共性逻辑;

  • 子类 OrderForm 只需关注订单提交的个性化逻辑,无需重复处理权限

需求场景 选择工具
定义 Props/Emits 类型、接口返回数据结构 接口(Interface)
仅约束组件 / 类必须实现的方法(无逻辑) 接口(Interface)
复用共性逻辑(如固定流程、公共方法) 抽象类(Abstract Class)
既需要约束结构,又需要复用逻辑 接口 + 抽象类(配合使用)
希望多实现(一个类遵循多个契约) 接口(多 implements)
相关推荐
三小河1 小时前
Vue3 组合式函数:能否作为模块级全局状态管理?
前端·javascript
nvd112 小时前
Gidgethub 使用指南
开发语言·python
6***x5452 小时前
TypeScript在全栈开发中的使用
前端·javascript·typescript
晴殇i2 小时前
Generator 在 JavaScript 中的应用与优势
前端·javascript
讨厌下雨的天空2 小时前
线程同步与互斥
java·开发语言
娶不到胡一菲的汪大东2 小时前
C# 泛型 委托 接口
开发语言·windows·c#
Antonio9152 小时前
【Swift】UIKit:UISegmentedControl、UISlider、UIStepper、UITableView和UICollectionView
开发语言·ios·swift
一只Icer2 小时前
哲学与代码:HTML5哲学动画
前端·html·html5
赣州云智科技的技术铺子2 小时前
AI运动小程序鸿蒙平台适配指南
javascript