当前位置: 首页 > news >正文

Vue 3 TypeScript 接口(Interface)使用

在 Vue 3 中使用 TypeScript 时,接口(Interface)是定义类型的重要工具。接口可以帮助我们明确组件 props、数据模型、函数签名等内容的类型结构,提高代码可读性和可维护性。

接口在 Vue 3 中的常见应用场景

1. 定义组件 Props 类型

// 用户信息接口
interface User {id: number;name: string;email: string;age?: number; // 可选属性
}// 在组件中使用
export default defineComponent({props: {// 使用接口定义props类型user: {type: Object as () => User, // 类型断言required: true},// 简单类型isActive: {type: Boolean,default: false}},setup(props) {// 现在可以安全访问props.user的属性const userName = computed(() => props.user.name);return { userName };}
});

2. 定义响应式数据模型

// 待办事项接口
interface TodoItem {id: number;title: string;completed: boolean;createdAt: Date;
}export default defineComponent({setup() {// 使用接口定义响应式数据const todos = ref<TodoItem[]>([{id: 1,title: '学习 Vue 3',completed: false,createdAt: new Date()}]);// 添加新待办事项的函数const addTodo = (title: string) => {const newTodo: TodoItem = {id: Date.now(),title,completed: false,createdAt: new Date()};todos.value.push(newTodo);};return { todos, addTodo };}
});

3. 定义复杂的状态对象

// 应用状态接口
interface AppState {isLoading: boolean;error: string | null;data: any[];page: number;
}export default defineComponent({setup() {// 使用接口定义状态对象const state = reactive<AppState>({isLoading: false,error: null,data: [],page: 1});// 获取数据的方法const fetchData = async () => {state.isLoading = true;state.error = null;try {const response = await fetch(`/api/data?page=${state.page}`);state.data = await response.json();} catch (err) {state.error = '获取数据失败';} finally {state.isLoading = false;}};return { state, fetchData };}
});

4. 定义事件发射类型

// 自定义事件接口
interface CustomEvents {(e: 'update:name', value: string): void;(e: 'delete', id: number): void;
}export default defineComponent({emits: ['update:name', 'delete'] as unknown as CustomEvents,setup(props, { emit }) {const updateName = (newName: string) => {// 类型安全的事件发射emit('update:name', newName);};const deleteItem = (id: number) => {// 类型安全的事件发射emit('delete', id);};return { updateName, deleteItem };}
});

5. 定义组合函数类型

// 计数器组合函数接口
interface Counter {count: Ref<number>;increment: () => void;decrement: () => void;reset: () => void;
}// 创建计数器的组合函数
export function useCounter(initialValue = 0): Counter {const count = ref(initialValue);const increment = () => count.value++;const decrement = () => count.value--;const reset = () => count.value = initialValue;return { count, increment, decrement, reset };
}

6. 定义 API 响应类型

// API 响应接口
interface ApiResponse<T> {status: 'success' | 'error';message: string;data: T;timestamp: Date;
}// 用户数据接口
interface UserData {id: number;name: string;email: string;
}// 在组件中使用
export default defineComponent({setup() {const userData = ref<UserData | null>(null);const fetchUser = async (id: number) => {const response = await fetch(`/api/users/${id}`);const result: ApiResponse<UserData> = await response.json();if (result.status === 'success') {userData.value = result.data;}};return { userData, fetchUser };}
});

接口高级用法

1. 接口继承

// 基础实体接口
interface BaseEntity {id: number;createdAt: Date;updatedAt: Date;
}// 用户接口继承基础实体
interface User extends BaseEntity {name: string;email: string;role: 'admin' | 'user';
}// 产品接口继承基础实体
interface Product extends BaseEntity {name: string;price: number;description: string;category: string;
}

2. 索引签名

// 字典接口
interface Dictionary<T> {[key: string]: T;
}// 在组件中使用
const colors: Dictionary<string> = {primary: '#3498db',secondary: '#2ecc71',danger: '#e74c3c'
};const permissions: Dictionary<boolean> = {canEdit: true,canDelete: false,canCreate: true
};

3. 函数类型接口

// 比较函数接口
interface Comparator<T> {(a: T, b: T): number;
}// 在组件中使用
const sortUsers = (users: User[], comparator: Comparator<User>) => {return [...users].sort(comparator);
};// 创建比较器
const byName: Comparator<User> = (a, b) => a.name.localeCompare(b.name);
const byDate: Comparator<User> = (a, b) => a.createdAt.getTime() - b.createdAt.getTime();

完整示例:使用接口的 Vue 3 组件

<template><div class="user-profile"><h2>{{ user.name }}</h2><p>邮箱: {{ user.email }}</p><p v-if="user.age">年龄: {{ user.age }}</p><div class="stats"><div class="stat-item"><span class="stat-label">文章数:</span><span class="stat-value">{{ stats.postCount }}</span></div><div class="stat-item"><span class="stat-label">关注者:</span><span class="stat-value">{{ stats.followerCount }}</span></div></div><button @click="updateName">更新用户名</button></div>
</template><script lang="ts">
import { defineComponent, PropType, reactive } from 'vue';// 定义用户接口
interface User {id: number;name: string;email: string;age?: number;
}// 定义用户统计数据接口
interface UserStats {postCount: number;followerCount: number;followingCount: number;
}export default defineComponent({props: {user: {type: Object as PropType<User>,required: true}},setup(props, { emit }) {// 使用接口定义响应式状态const stats = reactive<UserStats>({postCount: 24,followerCount: 128,followingCount: 56});// 更新用户名的函数const updateName = () => {const newName = prompt('请输入新的用户名:');if (newName) {// 发射自定义事件emit('update:name', newName);}};return { stats, updateName };}
});
</script><style scoped>
.user-profile {max-width: 400px;margin: 0 auto;padding: 20px;border: 1px solid #e1e1e1;border-radius: 8px;background-color: #fff;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}h2 {color: #2c3e50;margin-bottom: 10px;
}p {color: #7f8c8d;margin: 5px 0;
}.stats {display: flex;margin: 20px 0;border-top: 1px solid #eee;padding-top: 15px;
}.stat-item {flex: 1;text-align: center;
}.stat-label {display: block;color: #95a5a6;font-size: 0.9rem;
}.stat-value {display: block;font-size: 1.5rem;font-weight: bold;color: #3498db;
}button {background-color: #3498db;color: white;border: none;padding: 10px 15px;border-radius: 4px;cursor: pointer;font-size: 1rem;transition: background-color 0.3s;
}button:hover {background-color: #2980b9;
}
</style>

http://www.lryc.cn/news/587398.html

相关文章:

  • (一)SAP Group Reporting (GR) 集团财务合并解决方案套件概述
  • 数智管理学(三十三)
  • [论文阅读] 软件工程 | 首个德语软件工程情感分析黄金标准数据集:构建与价值解析
  • 【读书笔记】《Effective Modern C++》第二章:auto
  • 【论文阅读】Think Only When You Need with Large Hybrid-Reasoning Models
  • Datawhale AI 夏令营2025科大讯飞AI大赛<夏令营:用AI做带货视频评论分析>
  • 业务访问控制-ACL与包过滤
  • 【OpenGL ES】手撕一个mini版的Android native渲染框架
  • 串口学习和蓝牙通信HC05(第八天)
  • AI交互中的礼貌用语:“谢谢“的效用与代价分析
  • 09.获取 Python 列表的首尾元素与切片技巧
  • LLM大模型微调技术全景:从IFT、SFT到RLHF、DPO与PPO强化学习
  • 华擎B150M Pro4S魔改bios上8代U
  • AutoLabor-ROS-Python 学习记录——第一章 ROS概述与环境搭建
  • vue3 el-select默认选中
  • (33)记录描述窗体组件属性的枚举量 enum Qt :: WidgetAttribute, 简记为 WA_
  • 大模型微调(一):基于Swift框架进行自我认知微调(使用Lora微调Qwen3-8B模型)
  • MCU中的系统控制器(System Controller)是什么?
  • pthread_mutex_unlock函数的概念和用法
  • 手写muduo笔记
  • Clojure和Golang中的Channel有什么异同(TBC)
  • NumPy 中 np.c_ 的用法解析
  • Can I Trust Your Answer? Visually Grounded Video Question Answering
  • Python协程进阶:优雅终止与异常处理详解
  • Java 面向对象的特征(一)
  • Actor-Critic重要性采样原理
  • 在高并发场景下,仅依赖数据库机制(如行锁、版本控制)无法完全避免数据异常的问题
  • 用豆包AI云盘保存和分析录音文件
  • 维基艺术图片: 数据标注 (2)
  • java: DDD using oracle 21c