第一章:Vue与TypeScript初识
为什么选择TypeScript
说实话,我刚开始用Vue的时候,也是纯JavaScript一把梭。直到有一次,我接手了一个中型项目,光找类型错误就花了两天。嗯,从那以后,我就决定在Vue项目里全面引入TypeScript。
TypeScript能给你带来什么?说白了,就是类型安全。你想想看,JavaScript是动态类型,变量可以随时变成任何类型。这在小型项目里还好,一旦项目超过5万行代码,光靠人脑记住所有类型,几乎不可能。
核心价值:TypeScript在编译阶段就能捕获类型错误,而不是等到运行时才发现。我个人认为,这是它最大的价值所在。
我在项目中遇到过这样一个场景:一个接口返回的数据结构变了,前端没有及时更新类型定义,结果页面直接白屏。如果用了TypeScript,这种问题在编译时就会被发现。
TypeScript vs JavaScript:一个直观对比
| 特性 | JavaScript | TypeScript |
|---|---|---|
| 类型系统 | 动态类型 | 静态类型 |
| 错误发现时机 | 运行时 | 编译时 |
| IDE支持 | 基础提示 | 智能提示、自动补全 |
| 重构能力 | 手动查找替换 | 安全重构 |
| 学习成本 | 低 | 中等 |
我的建议:如果你正在开发一个长期维护的项目,或者团队人数超过3人,直接上TypeScript。短期看多花了点时间写类型,长期看省下的调试时间绝对值得。
Vue3 + TS 项目初始化
好,我们直接动手。创建一个Vue3 + TypeScript项目,我推荐用Vite。为什么?因为它快,真的快。
# 使用npm创建项目
npm create vite@latest my-vue-ts-app -- --template vue-ts
# 或者用yarn
yarn create vite my-vue-ts-app --template vue-ts
# 进入项目目录
cd my-vue-ts-app
# 安装依赖
npm install
创建完成后,你会看到这样的项目结构。我来逐个解释每个文件的作用。
项目结构解析
my-vue-ts-app/
├── index.html # 入口HTML文件
├── package.json # 项目配置和依赖
├── tsconfig.json # TypeScript配置文件
├── vite.config.ts # Vite构建配置
├── env.d.ts # 环境类型声明
├── src/
│ ├── main.ts # 应用入口文件
│ ├── App.vue # 根组件
│ ├── components/ # 组件目录
│ ├── assets/ # 静态资源
│ └── style.css # 全局样式
└── public/ # 公共资源
关键文件详解
tsconfig.json — 这是TypeScript的核心配置。我习惯这样配置:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"noEmit": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
注意:我曾经因为忘了配置 paths 别名,导致项目里到处都是 ../../../components 这种路径。后来重构时改配置,花了整整一天。所以一开始就把路径别名配好,省心。
env.d.ts — 这个文件用来声明Vue单文件组件的类型。没有它,TypeScript不认识 .vue 文件。
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
vite.config.ts — Vite的配置文件,用TypeScript写,天然支持类型提示。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
}
})
第一个TypeScript组件
我们来写一个简单的计数器组件,感受一下TypeScript在Vue中的用法。
<script setup lang="ts">
import { ref } from 'vue'
// 显式声明类型
const count = ref<number>(0)
// 带类型的函数
function increment(): void {
count.value++
}
// 带参数和返回类型的函数
function add(amount: number): number {
count.value += amount
return count.value
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+1</button>
<button @click="add(5)">+5</button>
</div>
</template>
小技巧:在 <script setup> 里加上 lang="ts",Vue就会自动启用TypeScript支持。你写 ref<number>(0) 时,IDE会给你完整的类型提示。
避坑指南
我曾经犯过一个低级错误:在 script setup 里忘了加 lang="ts",结果写了半天类型注解,IDE一点反应都没有。后来检查才发现,Vue默认是JavaScript模式。
还有一次,我在 tsconfig.json 里把 strict 设成了 false,想着先跑起来再说。结果项目越写越大,类型错误越来越多,最后不得不花一周时间补类型。所以我的建议是:从一开始就开启严格模式。
小结
这一章我们聊了为什么选择TypeScript,怎么初始化一个Vue3 + TS项目,以及项目里每个文件是干什么的。你想想看,有了类型系统,你的代码就像有了说明书,别人接手你的项目时,光看类型定义就能理解七八分。
下一章,我们会深入Vue3的Composition API,看看TypeScript如何与 ref、reactive、computed 这些核心API完美配合。到时候我会分享一些我在实际项目中踩过的坑,保证让你少走弯路。