当前位置: 首页 > 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.dtcms.com/a/277341.html

相关文章:

  • 反射内存卡的使用
  • 【Linux系统与网络编程】13:线程同步
  • AWS Lambda Container 方式部署 Flask 应用并通过 API Gateway 提供访问
  • C++ 模板元编程 type_traits
  • RedisJSON 技术揭秘`JSON.ARRTRIM`用窗口裁剪,让数组保持“刚刚好”
  • 5G NR PDCCH之处理流程
  • [Nagios Core] CGI接口 | 状态数据管理.dat | 性能优化
  • k8s存储入门
  • RabbitMQ 之仲裁队列
  • Matplotlib 中 plt.pcolormesh 函数的使用详解
  • 【sql学习之拉链表】
  • 【LLM-Agent】Qwen-Agent智能体框架使用
  • trySend、Channel 和 Flow 的工作原理
  • 【CMake】CMake创建、安装、使用静态库和动态库
  • 操作系统-第四章存储器管理和第五章设备管理-知识点整理(知识点学习 / 期末复习 / 面试 / 笔试)
  • 【hivesql 已知维度父子关系加工层级表】
  • C++每日刷题day2025.7.13
  • 什么是RAG(Retrieval-Augmented Generation)?一文读懂检索增强生成
  • RabbitMQ面试精讲 Day 2:RabbitMQ工作模型与消息流转
  • 12.I/O复用
  • 前端性能与可靠性工程:资源优化 - 加载性能的“低垂果实”
  • 从零开始学习深度学习-水果分类之PyQt5App
  • SpringBoot集成Redis、SpringCache
  • C++ 强制类型转换
  • 【操作系统】strace 跟踪系统调用(一)
  • (LeetCode 每日一题) 2410. 运动员和训练师的最大匹配数(排序、双指针)
  • es里为什么node和shard不是一对一的关系
  • Augment AI 0.502.0版本深度解析:Task、Guidelines、Memory三大核心功能实战指南
  • 将 NumPy 数组展平并转换为 Python 列表
  • 1.1.5 模块与包——AI教你学Django