【Vue】TypeScript与Vue3集成

news2025/4/25 10:44:21

在这里插入图片描述

个人主页:Guiat
归属专栏:Vue

在这里插入图片描述

文章目录

  • 1. 前言
  • 2. 环境准备与基础搭建
    • 2.1. 安装 Node.js 与 npm/yarn/pnpm
    • 2.2. 创建 Vue3 + TypeScript 项目
      • 2.2.1. 使用 Vue CLI
      • 2.2.2. 使用 Vite(推荐)
        • 2.2.3. 目录结构简述
  • 3. Vue3 + TS 基础语法整合
    • 3.1. Composition API 集成 TypeScript
      • 3.1.1. 基础组件写法
      • 3.1.2. Props 与类型约束
      • 3.1.3. Emits 事件类型声明
    • 3.2. Options API 简要对比
  • 4. TypeScript 类型系统与 Vue3 深度融合
    • 4.1. 基本类型断言
    • 4.2. 泛型加强
      • 4.2.1. `ref<T>`
      • 4.2.2. `defineProps<T>`, `defineEmits<T>`
    • 4.3. 类型辅助工具活用
      • 4.3.1. 类型导出 reuse
      • 4.3.2. 联合类型、类型推断
  • 5. 组件开发全流程:TypeScript 全类型实践
    • 5.1. 父子组件 Props + Emits 综合举例
      • 5.1.1. 子组件定义
      • 5.1.2. 父组件使用
    • 5.2. 插槽与类型声明
  • 6. 全局属性与模块类型扩展
    • 6.1. app.config.globalProperties 类型扩展
      • 6.1.1. 类型声明
      • 6.1.2. 组件中类型无误调用
  • 7. TS 下的常用第三方库引入与类型声明
    • 7.1. 以 Axios 为例
      • 7.1.1. 安装与引入
      • 7.1.2. 类型化 Api 封装
      • 7.1.3. 组件调用
    • 7.2. 第三方库缺失类型声明问题
  • 8. Vue Router & Pinia 全类型支持
    • 8.1. 路由类型保驾护航
      • 8.1.1. 安装
      • 8.1.2. 路由元数据类型增强
      • 8.1.3. 全局类型合并扩展(如 TS 智能感知 meta)
    • 8.2. Pinia 全类型示例
      • 8.2.1. 安装
      • 8.2.2. 定义类型安全 store
      • 8.2.3. 组件类型安全调用
  • 9. 综合场景实践
    • 9.1. 类型安全的表单组件
      • 9.1.1. 定义表单字段类型
      • 9.1.2. 组件使用类型安全表单 state
      • 9.1.3. 集成第三方表单库(如 vee-validate)
  • 10. 典型架构场景图表分析
    • 10.1. 项目类型传递/共享关系图
    • 10.2. 业务拆包与类型定义分层
  • 11. TypeScript + Vue3 最佳实践要点
  • 12. 总结

正文


1. 前言

TypeScript 作为现代前端开发的主流静态类型语言,极大增强了代码的规范性和可维护性。Vue3 作为前端主流框架,官方也对 TypeScript 提供了全力支持。TypeScript 与 Vue3 的集成不仅能够提升开发效率,还能显著减少运行时错误,是现代企业项目的首选。

本文将以多级阿拉伯数字标题的方式,系统讲解 TypeScript 与 Vue3 集成的各个方面,涵盖环境搭建、基础语法整合、类型声明、组件开发、全局属性、第三方库引入、常见场景实践以及最佳实践建议。同时,配以典型代码示例和关键结构图表,助力理解。

**注意:**本文不会涉及 Vue3 的响应式原理与数据绑定相关内容,专注于 TypeScript 实战应用。

2. 环境准备与基础搭建

2.1. 安装 Node.js 与 npm/yarn/pnpm

TypeScript 与 Vue3 需借助现代 Node.js 生态环境,推荐使用 LTS 版本。

node -v
npm -v  # 或 yarn -v / pnpm -v

2.2. 创建 Vue3 + TypeScript 项目

2.2.1. 使用 Vue CLI

npm install -g @vue/cli
vue create my-vue3-ts-app
# 选择 Vue 3、手动配置特性,勾选 TypeScript

2.2.2. 使用 Vite(推荐)

Vite 是新一代前端构建工具,适用于现代 Vue3 项目。

npm create vite@latest
# 选择 vue + TypeScript 选项
cd my-vue3-ts-app && npm install
2.2.3. 目录结构简述
my-vue3-ts-app/
│
├── src/
│   ├── components/
│   ├── App.vue
│   ├── main.ts
│   └── ...
│
├── tsconfig.json            # TypeScript 配置
├── vite.config.ts           # 构建工具配置
└── package.json

图表分析:项目结构

项目根目录
src
tsconfig.json
vite.config.ts
App.vue
main.ts
components

3. Vue3 + TS 基础语法整合

Vue3 支持两种主流的组合方式:Options API + TSComposition API + TS。推荐编写业务逻辑时使用 Composition API。

3.1. Composition API 集成 TypeScript

3.1.1. 基础组件写法

src/components/HelloWorld.vue

<script lang="ts" setup>
import { ref } from "vue";

const message = ref<string>("Hello TypeScript + Vue3!");
</script>

<template>
  <div>{{ message }}</div>
</template>
  • lang="ts" 告诉 Vue 以 TypeScript 解析 <script>
  • setup 语法糖配合 TS 类型推导(ref)

3.1.2. Props 与类型约束

<script lang="ts" setup>
import { defineProps } from 'vue';

interface Props {
  msg: string;
  count?: number;
}

const props = defineProps<Props>();
</script>

<template>
  <h1>{{ props.msg }}</h1>
  <p v-if="props.count">Count: {{ props.count }}</p>
</template>

3.1.3. Emits 事件类型声明

<script lang="ts" setup>
import { defineEmits } from "vue";

const emit = defineEmits<{
  (event: 'increment', value: number): void
}>();

function handleClick() {
  emit('increment', 1);
}
</script>

3.2. Options API 简要对比

虽然不推荐,新旧项目迁移时经常遇到

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    title: String,
  },
  methods: {
    sayHello(msg: string): void {
      console.log(msg);
    }
  }
})
</script>

4. TypeScript 类型系统与 Vue3 深度融合

Vue3 充分利用了 TypeScript 的高级类型。

4.1. 基本类型断言

const name: string = "Alice";
const age: number = 25;

4.2. 泛型加强

ref<T>, defineProps<T>, defineEmits<T>, defineExpose<T>

4.2.1. ref<T>

import { ref } from "vue";

const user = ref<{name: string, age: number}>({ name: 'Bob', age: 30 });

4.2.2. defineProps<T>, defineEmits<T>

见前文 3.1.2/3.1.3 示例

4.3. 类型辅助工具活用

代码体验进一步提升:

4.3.1. 类型导出 reuse

types/user.ts

export interface User {
  id: number;
  name: string;
  email: string;
}

组件中使用:

<script lang="ts" setup>
import type { User } from '@/types/user'
const props = defineProps<{ user: User }>();
</script>

4.3.2. 联合类型、类型推断

type Status = 'success' | 'error' | 'loading';

const status = ref<Status>('loading');

5. 组件开发全流程:TypeScript 全类型实践

5.1. 父子组件 Props + Emits 综合举例

5.1.1. 子组件定义

src/components/Counter.vue

<script lang="ts" setup>
import { defineProps, defineEmits } from "vue";
interface Props {
  modelValue: number
}
const props = defineProps<Props>();

const emit = defineEmits<{
  (event: 'update:modelValue', value: number): void
}>();

function inc() {
  emit('update:modelValue', props.modelValue + 1)
}
function dec() {
  emit('update:modelValue', props.modelValue - 1)
}
</script>
<template>
  <button @click="dec">-</button>
  <span>{{ props.modelValue }}</span>
  <button @click="inc">+</button>
</template>

5.1.2. 父组件使用

<script lang="ts" setup>
import { ref } from 'vue'
import Counter from './components/Counter.vue'

const count = ref<number>(0)
</script>
<template>
  <Counter v-model="count"/>
  <p>父组件当前值:{{ count }}</p>
</template>

5.2. 插槽与类型声明

插槽内容可通过 TS 接口声明类型。

<script lang="ts" setup>
interface HeaderSlotProps {
  title: string
}
defineSlots<{
  header(props: HeaderSlotProps): void
}>()
</script>
<template>
  <slot name="header" :title="'My Title'"/>
</template>

6. 全局属性与模块类型扩展

6.1. app.config.globalProperties 类型扩展

入口 main.ts 设置全局属性(如 $filters

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.config.globalProperties.$filters = {
  capitalize(str: string) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
}
app.mount('#app')

6.1.1. 类型声明

新建 src/types/vue.d.ts

import { ComponentCustomProperties } from 'vue'

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $filters: {
      capitalize(str: string): string
    }
  }
}

6.1.2. 组件中类型无误调用

<script lang="ts" setup>
const str = $filters.capitalize('hello world')
</script>

7. TS 下的常用第三方库引入与类型声明

7.1. 以 Axios 为例

7.1.1. 安装与引入

npm i axios
npm i -D @types/axios

7.1.2. 类型化 Api 封装

import axios from 'axios'

export interface ApiResponse<T> {
  code: number;
  data: T;
  message: string;
}
export function getUser(userId: number) {
  return axios.get<ApiResponse<User>>(`/api/user/${userId}`);
}

7.1.3. 组件调用

<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { getUser } from '@/api/user'
import type { User } from '@/types/user'

const user = ref<User>()
onMounted(async () => {
  const res = await getUser(123)
  if(res.data.code === 0) user.value = res.data.data
})
</script>

7.2. 第三方库缺失类型声明问题

如遇第三方库没有 type,需自己声明。

新建 src/types/some-lib.d.ts:

declare module 'some-lib' {
  export function hello(name: string): void;
}

8. Vue Router & Pinia 全类型支持

8.1. 路由类型保驾护航

8.1.1. 安装

npm i vue-router
# Vue3 新版已内置类型

8.1.2. 路由元数据类型增强

定义:

import { RouteRecordRaw } from 'vue-router'
interface Meta {
  requiresAuth?: boolean;
  title?: string;
}

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Home',
    component: () => import('@/views/Home.vue'),
    meta: {
      requiresAuth: true,
      title: '首页'
    } as Meta
  }
]

8.1.3. 全局类型合并扩展(如 TS 智能感知 meta)

src/types/router.d.ts

import 'vue-router'
declare module 'vue-router' {
  interface RouteMeta {
    requiresAuth?: boolean;
    title?: string;
  }
}

8.2. Pinia 全类型示例

8.2.1. 安装

npm i pinia

8.2.2. 定义类型安全 store

src/stores/counter.ts

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

8.2.3. 组件类型安全调用

<script lang="ts" setup>
import { useCounterStore } from '@/stores/counter'

const counterStore = useCounterStore()
counterStore.increment()
</script>

Pinia 全面使用泛型,无需额外类型声明即可获得全类型推断。


9. 综合场景实践

对真实业务有指导意义的高阶运用:

9.1. 类型安全的表单组件

9.1.1. 定义表单字段类型

interface FormData{
  username: string,
  password: string,
  remember: boolean
}

9.1.2. 组件使用类型安全表单 state

<script lang="ts" setup>
import { reactive } from 'vue'
const form = reactive<FormData>({
  username: "",
  password: "",
  remember: false,
})
</script>
<template>
  <input v-model="form.username" placeholder="用户名">
  <input v-model="form.password" type="password" placeholder="密码">
  <input type="checkbox" v-model="form.remember"> 记住我
</template>

9.1.3. 集成第三方表单库(如 vee-validate)

vee-validate 已内置类型支持,可直接配合类型接口。


10. 典型架构场景图表分析

10.1. 项目类型传递/共享关系图

props
emit
import type
import type
返回类型
useStore
App.tsx
CompA.vue
CompB.vue
Types.ts
Api.ts
Stores.ts
  • 统一类型接口放到 types,Api 层/组件/Pinia 共享
  • 保证全链路的数据安全性

10.2. 业务拆包与类型定义分层

types/ domain 对象定义
api/ 与后端联调
stores/ Pinia 类型
components/ 前端复用组件

11. TypeScript + Vue3 最佳实践要点

  1. 统一类型声明管理:将类型接口集中管理于 src/types/ 文件夹。
  2. 避免 any:任何时候都应当追求类型精确约束而不是填充 any。
  3. 泛型更优雅ref<T>defineProps<T>、Api 响应等全部泛型化声明。
  4. 配置 tsconfig.json:合理配置路径映射和检测规则,提升开发体验。
  5. 配合 IDE 插件和类型检查工具:如 Volar、ESLint/TSLint、Prettier。
  6. 定期类型升级和重构:利用类型系统减少技术债。
  7. 善用类型工具:如 Partial<T>Pick<T>Record<K,V> 等。
  8. 组件 slot、emit 等交互全类型声明

12. 总结

TypeScript 与 Vue3 的深度集成为现代前端开发带来革命性的进步。从环境搭建到项目结构优化,从 Props/Emits/Slots 全链路类型声明,到 Pinia、Router、第三方库的类型增强,TS 均可充分发挥威力,极大地提高了代码的可靠性开发幸福感。

前端开发者应尽早拥抱 TypeScript + Vue3,借助强大的类型系统,让团队开发协作更高效、更健壮。


结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342349.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux之七大难命令(The Seven Difficult Commands of Linux)

Linux之七大难命令 、背景 作为Linux的初学者&#xff0c;肯定要先掌握高频使用的指令&#xff0c;这样才能让Linux的学习在短时间内事半功倍。但是&#xff0c;有些指令虽然功能强大&#xff0c;但因参数多而让初学者们很害怕&#xff0c;今天介绍Linux中高频使用&#xff0…

5.3.1 MvvmLight以及CommunityToolkit.Mvvm介绍

MvvmLight、CommunityToolkit.Mvvm是开源包,他们为实现 MVVM(Model-View-ViewModel)模式提供了一系列实用的特性和工具,能帮助开发者更高效地构建 WPF、UWP、MAUI 等应用程序。 本文介绍如下: 一、使用(旧)的MvvmLight库 其特点如下,要继承的基类是ViewModelBase;且使用…

Dbeaver 执行 SQL 语句和执行 SQL 脚本的区别

执行 SQL 语句 执行 SQL 语句对应图标&#xff1a; 适用于执行单个 SQL 的情形&#xff0c;默认是在光标处或选中的文本上执行 SQL 查询。 实际上同时选择多个 SQL 并通过该方式去执行也可能成功&#xff0c;只是有失败的风险。因此不建议使用它来同时执行多个 SQL 语句。 情况…

《Python3网络爬虫开发实战(第二版)》配套案例 spa6

Scrape | Moviehttps://spa6.scrape.center/ 请求影片列表api时&#xff0c;不仅有分页参数&#xff0c;还多了一个token&#xff0c;通过重发请求发现token有时间限制&#xff0c;所以得逆向token的生成代码。 通过xhr断点定位到接口请求位置 刷新页面或者点翻页按钮&#x…

Python基础语法:字面量,注释,关键字,标识符,变量和引用,程序执行的3大流程

目录 字面量&#xff08;数据的类型&#xff09; 字面量的含义 常见字面量类型&#xff08;6种&#xff09; 输出各类字面量&#xff08;print语句&#xff09; 注释&#xff08;单行和多行注释&#xff09; 注释的作用 单行注释和多行注释 单行注释&#xff08;ctrl/&a…

SPL 量化 获取数据

下载数据 我们将股票数据分享在百度网盘上供下载&#xff0c;每工作日更新。 目前可供下载的数据有 A 股的日 K 线数据、股票代码列表和上市公司的基本面数据 下载链接&#xff1a; 百度网盘 下载数据的文件格式为 btx&#xff0c;是 SPL 的特有二进制格式。 btx 称为集文…

Rust 学习笔记:安装 Rust

Rust 学习笔记&#xff1a;安装 Rust Rust 学习笔记&#xff1a;安装 Rust在 Windows 上安装 Rust命令行创建 Rust 项目在 Mac/Linux 上安装 Rust一些命令升级卸载cargo -hrustc -h 安装 RustRoverrust-analyzer Rust 学习笔记&#xff1a;安装 Rust 在 Windows 上安装 Rust …

编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)

前言 在使用终端编译 C 程序时&#xff0c;报错&#xff1a; 或类似提示&#xff0c;意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g&#xff0c;适用于新手或 C 入门阶段的你。 什么是 g&#xff1f; g 是 GN…

html单页业务介绍源码

源码介绍 html单页业务介绍源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行 效果预览 源码免费获取 html单页业务介绍源码

单体OJ项目

单体项目版本、微服务版还需我再钻研钻研。 项目介绍 在系统前台&#xff0c;管理员可以创建、管理题目;用户可以自由搜索题目、阅读题目、编写并提交代码。 在系统后端&#xff0c;能够根据管理员设定的题目测试用例在代码沙箱 中对代码进行编译、运行、判断输出是否正确。 其…

豆包桌面版 1.47.4 可做浏览器,免安装绿色版

自己动手升级更新办法&#xff1a; 下载新版本后安装&#xff0c;把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件&#xff0c;拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件&#xff0c;就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…

【MySQL】索引失效问题详解

目录 1. 最左前缀原则 2. 条件左边有函数或运算 3. 隐式类型转换 4. LIKE 模糊查询以 % 开头 5、MySQL 优化器选择全表扫描 ⭐对 in 关键字特别说明⭐ &#xff08;1&#xff09;列表太大时&#xff0c;走全表扫描了 &#xff08;2&#xff09;隐式类型转换 &#xff…

优选算法第十讲:字符串

优选算法第十讲&#xff1a;字符串 1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘 1.最长公共前缀 2.最长回文子串 3.二进制求和 4.字符串相乘

【扣子Coze 智能体案例四】五行八卦占卜智能体

目录 一、意图识别 二、时间格式转换 三、八字转换 四、八字提取 五、八字提取2 六、数据汇总 七、统计五行占比 八、雷达图生成 九、表格生成 十、AI占卜 十一、结束节点 一、意图识别 用户输入的信息包含各种时间格式的年月日时 用户输入的信息包含天干地支八字…

5.学习笔记-SpringMVC(P61-P70)

SpringMVC-SSM整合-接口测试 (1)业务层接口使用junit接口做测试 (2)表现层用postman做接口测试 (3)事务处理— 1&#xff09;在SpringConfig.java&#xff0c;开启注解&#xff0c;是事务驱动 2&#xff09;配置事务管理器&#xff08;因为事务管理器是要配置数据源对象&…

【专题刷题】二分查找(一):深度解刨二分思想和二分模板

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

硬核解析!电动汽车能耗预测与续驶里程的关键技术研究

引言 随着电动汽车的普及,续航里程和能耗表现成为用户关注的核心痛点。然而,表显续航与实际续航的差异、低温环境下的电量衰减等问题始终困扰着消费者。本文基于《电动汽车能耗预测与续驶里程研究》的实验成果,深入剖析电动汽车能耗预测的核心模型、多环境测试方法及续航里…

【OceanBase相关】01-OceanBase数据库部署实践

文章目录 一、前言1、介绍说明2、部署方案二、部署说明1、环境准备2、软件安装2.1、安装OAT2.2、安装OCP3、软件部署三、集群管理1、MySQL租户管理四、Q&A1、OBServer 服务器重启后 observer 进程未能自动启动1.1、问题说明1.2、解决措施2、ERROR 1235 (0A000) at line 1: …

详细讲解 QMutex 线程锁和 QMutexLocker 自动锁的区别

详细讲解 QMutex 线程锁和 QMutexLocker 自动锁的区别 下面我们详细拆解 Qt 中用于线程同步的两个核心类&#xff1a;QMutex 和 QMutexLocker。 &#x1f9f1; 一、什么是 QMutex&#xff1f; QMutex 是 Qt 中的互斥锁&#xff08;mutex&#xff09;类&#xff0c;用于防止多个…

PCB 过孔铜厚的深入指南

***前言&#xff1a;在上一期的文章中介绍了PCB制造的工艺流程&#xff0c;但仍然想在过孔的铜厚和PCB的过孔厚径比两个方面再深入介绍。 PCB铜厚的定义 电路中铜的厚度以盎司(oz)**表示。那么&#xff0c;为什么用重量单位来表示厚度呢? 盎司(oz)的定义 将1盎司(28.35 克)的铜…