在 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([
{
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({
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;
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 {
status: 'success' | 'error';
message: string;
data: T;
timestamp: Date;
}
// 用户数据接口
interface UserData {
id: number;
name: string;
email: string;
}
// 在组件中使用
export default defineComponent({
setup() {
const userData = ref(null);
const fetchUser = async (id: number) => {
const response = await fetch(`/api/users/${id}`);
const result: ApiResponse = 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 {
[key: string]: T;
}
// 在组件中使用
const colors: Dictionary = {
primary: '#3498db',
secondary: '#2ecc71',
danger: '#e74c3c'
};
const permissions: Dictionary = {
canEdit: true,
canDelete: false,
canCreate: true
};
3. 函数类型接口
// 比较函数接口
interface Comparator {
(a: T, b: T): number;
}
// 在组件中使用
const sortUsers = (users: User[], comparator: Comparator) => {
return [...users].sort(comparator);
};
// 创建比较器
const byName: Comparator = (a, b) => a.name.localeCompare(b.name);
const byDate: Comparator = (a, b) =>
a.createdAt.getTime() - b.createdAt.getTime();
完整示例:使用接口的 Vue 3 组件
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, required: true } }, setup(props, { emit }) { // 使用接口定义响应式状态 const stats = reactive({ postCount: 24, followerCount: 128, followingCount: 56 }); // 更新用户名的函数 const updateName = () => { const newName = prompt('请输入新的用户名:'); if (newName) { // 发射自定义事件 emit('update:name', newName); } }; return { stats, updateName }; } }); .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; }
到此这篇关于Vue 3 TypeScript 接口(Interface)使用的文章就介绍到这了,更多相关Vue TypeScript 接口内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!
