Vue 3 + TypeScript 从基础到熟练指南
一. 基础环境搭建
1.创建项目(使用 Vite)
使用Vue CLI或Vite创建项目。这里以Vite为例(推荐):
npm create vite@latest my-vue-app -- --template vue-ts
2.核心依赖:
"dependencies": {"vue": "^3.4.0","pinia": "^2.1.7","vue-router": "^4.3.0"
}
二. 项目结构
创建后,项目结构大致如下:
my-vue-app
├── public
├── src
│ ├── assets
│ ├── components
│ ├── App.vue
│ └── main.ts
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts
三. 基本组件编写
在Vue单文件组件(SFC)中,我们使用<script setup lang="ts">
语法糖来编写Composition API的代码。
例如,创建一个HelloWorld组件:<!-- src/components/HelloWorld.vue -->
<template><div><h1>{{ greeting }}</h1><p>Count: {{ count }}</p><button @click="increment">Increment</button></div>
</template>
组合式 API + TS
<script setup lang="ts">
import { ref } from 'vue';const greeting = ref<string>('Hello, Vue 3 with TypeScript!');
const count = ref<number>(0);function increment(): void {count.value++;
}
</script>
四. 类型定义
TypeScript的核心是类型。在Vue组件中,我们可以为props、emits、reactive状态等定义类型。
Props类型
使用defineProps
宏,它支持类型推断。我们可以使用接口或类型别名:
<script setup lang="ts">
interface Props {msg: string;count?: number; // 可选
}const props = defineProps<Props>();
</script>
Emits类型
使用defineEmits
宏:
<script setup lang="ts">
const emit = defineEmits<{(e: 'change', id: number): void;(e: 'update', value: string): void;
}>();
</script>
五、状态管理(Pinia + TS)
Vue Router
安装:
npm install vue-router@4
创建路由文件(使用TS):
// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';const routes: Array<RouteRecordRaw> = [{ path: '/', component: () => import('@/views/Home.vue') },{ path: '/about', component: () => import('@/views/About.vue') },
];const router = createRouter({history: createWebHistory(),routes,
});export default router;
Pinia(替代Vuex)
安装:
npm install pinia
创建store:
// stores/counter.ts
import { defineStore } from 'pinia'interface CounterState {count: number
}export const useCounterStore = defineStore('counter', {state: (): CounterState => ({count: 0}),actions: {increment(step: number = 1) {this.count += step}}
})
在组件中使用:
<script setup lang="ts">
import { useCounterStore } from '@/store/counterStore';const counterStore = useCounterStore();
</script>
六、路由配置(Vue Router + TS)
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'declare module 'vue-router' {interface RouteMeta {requiresAuth?: boolean}
}const routes = [{path: '/',component: () => import('@/views/Home.vue'),meta: { requiresAuth: true }}
]export default createRouter({history: createWebHistory(),routes
})
七、高级类型技巧
1.自定义类型守卫
function isAxiosError(error: unknown): error is AxiosError {return (error as AxiosError).isAxiosError !== undefined
}
2.泛型组件
<script setup lang="ts" generic="T extends { id: number }">
defineProps<{items: T[]selected: T | null
}>()
</script>
在复杂的应用中,我们可能需要使用更高级的TypeScript特性。例如,在组合式函数中使用泛型:
// 一个简单的响应式状态封装
import { ref } from 'vue';export function useState<T>(initialState: T) {const state = ref<T>(initialState);function setState(newState: T): void {state.value = newState;}return [state, setState] as const;
}
八. 组合式函数(Composables)
组合式函数是Vue 3 Composition API的核心,用于封装和复用逻辑。我们可以使用TypeScript来增强它们。
1.TS 配置优化(tsconfig.json)
{"compilerOptions": {"strict": true,"types": ["vite/client"],"vueCompilerOptions": {"target": 3.3}}
}
2.函数封装
(1) axios组合式函数封装
// composables/useFetch.ts
import axios, { AxiosResponse } from 'axios'export default async function useFetch<T>(url: string): Promise<T> {const response: AxiosResponse<T> = await axios.get(url)return response.data
}
(2) 计数器组合函数封装
// src/composables/useCounter.ts
import { ref } from 'vue';export default function useCounter(initialValue: number = 0) {const count = ref(initialValue);function increment(): void {count.value++;}function decrement(): void {count.value--;}return {count,increment,decrement,};
}
组件中使用:
<script setup lang="ts">
import useCounter from '@/composables/useCounter';const { count, increment, decrement } = useCounter(0);
</script>
九. 测试
使用Jest或Vitest进行单元测试。确保类型在测试中也被正确使用。
十. 逐步深入
- 学习Vue 3响应式原理(ref, reactive, computed, watch等)与TypeScript结合。
- 掌握组件通信(props, emits, provide/inject)的类型安全。
- 学习使用第三方库(如Axios)的类型定义。
- 使用TypeScript编写自定义指令、插件等。
十一、调试与优化
- Vue Devtools:启用 TypeScript 支持
- ESLint 配置:
{"extends": ["plugin:vue/vue3-recommended","@vue/typescript/recommended"]
}
学习路径建议
基础阶段(1-2周)
- 组合式 API 核心语法
- 组件 props/emits 类型声明
- 基础类型操作(
interface
,type
)
进阶阶段(2-4周)
- Pinia 状态管理
- 路由类型安全
- 泛型组件开发
- TS 工具类型(
Partial
,Pick
)
精通阶段(持续实践)
- 复杂类型体操
- 类型安全的外部库集成
- 性能优化类型策略
- 自定义类型声明文件(*.d.ts)