下面给你一份 Vue 3 + TypeScript 下接口 (interface) 使用的详解示例,从基础到进阶,涵盖组件 props、响应式数据、函数类型、泛型以及与 Vue 组合式 API 的结合实践。
1️⃣ 基础接口使用
// 定义一个接口
interface User {
id: number
name: string
age?: number // 可选属性
}
// 使用接口声明变量
const user1: User = {
id: 1,
name: 'Alice',
}
// 错误示范:缺少 id
// const user2: User = { name: 'Bob' } // ❌ TS 会报错
2️⃣ 接口与函数类型
interface Greeter {
(name: string): string
}
const greet: Greeter = (name) => {
return `Hello, ${name}!`
}
console.log(greet('Alice')) // Hello, Alice!
3️⃣ 接口继承(Extends)
interface Person {
name: string
age: number
}
interface Employee extends Person {
employeeId: string
}
const emp: Employee = {
name: 'Tom',
age: 25,
employeeId: 'E1001'
}
4️⃣ Vue 3 + TypeScript 使用接口示例
4.1 定义 Props 接口
// UserCard.vue
<script lang="ts" setup>
import { defineProps } from 'vue'
// 定义接口
interface User {
id: number
name: string
age?: number
}
// 使用接口定义 props
const props = defineProps<{
user: User
showAge?: boolean
}>()
</script>
<template>
<div>
<p>名字: {{ props.user.name }}</p>
<p v-if="props.showAge">年龄: {{ props.user.age }}</p>
</div>
</template>
✅ 好处:
- props 有类型约束
- 支持可选属性
- 编辑器提示强大
4.2 定义响应式对象
<script lang="ts" setup>
import { reactive } from 'vue'
interface Product {
id: number
name: string
price: number
}
const product = reactive<Product>({
id: 1,
name: 'MacBook Pro',
price: 1999
})
// 修改属性
product.price = 1899
</script>
4.3 接口定义函数参数
interface Calculator {
(a: number, b: number): number
}
const add: Calculator = (a, b) => a + b
const multiply: Calculator = (a, b) => a * b
在 Vue 事件中使用:
const handleClick = (fn: Calculator) => {
console.log(fn(2, 3))
}
5️⃣ 接口与泛型结合
interface ApiResponse<T> {
code: number
data: T
message: string
}
// 示例接口返回 User 数据
const res: ApiResponse<User> = {
code: 200,
data: { id: 1, name: 'Alice' },
message: 'ok'
}
在 Vue 组件中可直接使用泛型:
import { ref } from 'vue'
const response = ref<ApiResponse<User>>({
code: 0,
data: { id: 0, name: '' },
message: ''
})
6️⃣ 高级接口:索引签名 & 交叉类型
6.1 索引签名
interface StringMap {
[key: string]: string
}
const obj: StringMap = {
name: 'Alice',
city: 'Beijing'
}
6.2 交叉类型(组合多个接口)
interface A { a: number }
interface B { b: string }
type C = A & B
const objC: C = { a: 10, b: 'Hello' }
7️⃣ Vue 3 组合式 API 综合示例
<script lang="ts" setup>
import { reactive, ref } from 'vue'
interface Todo {
id: number
title: string
done: boolean
}
const todos = reactive<Todo[]>([
{ id: 1, title: 'Learn Vue 3', done: false },
{ id: 2, title: 'Learn TypeScript', done: true }
])
const newTodo = ref<Todo>({ id: 3, title: 'Write demo', done: false })
const addTodo = () => {
todos.push({ ...newTodo.value })
newTodo.value.title = ''
}
const toggleTodo = (todo: Todo) => {
todo.done = !todo.done
}
</script>
<template>
<div>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" v-model="todo.done" @change="toggleTodo(todo)" />
{{ todo.title }} - {{ todo.done ? '完成' : '未完成' }}
</li>
</ul>
<input v-model="newTodo.title" placeholder="新任务" />
<button @click="addTodo">添加</button>
</div>
</template>
✅ 特点:
- todo 类型强约束
- 新增、修改都自动提示类型
- Vue 响应式和 TS 类型结合完美
8️⃣ 总结
- interface vs type:
- interface 可以声明对象、函数类型、继承、合并声明
- type 更适合联合类型、交叉类型、基本类型别名
- Vue 3 + TS 最常用场景:
defineProps<Interface>()reactive<Interface>()/ref<Interface>()- 函数参数类型
- API 返回值泛型类型
- 优势:
- 代码可维护性强
- 编辑器提示完善
- 组件 props / 事件 /状态都有类型安全