【Vue】TypeScript与Vue3集成

在这里插入图片描述

个人主页: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.mzph.cn/diannao/80294.shtml

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

相关文章

高防IP是什么

"高防IP"是指"高防护IP"&#xff0c;是一种防御DDoS&#xff08;分布式拒绝服务攻击&#xff09;的网络安全服务。在分布式拒绝服务攻击中&#xff0c;攻击者会利用许多不同的计算机或者其他设备&#xff0c;通过向目标发送大量的网络请求来尝试使目标服务…

手机访问电脑端Nginx服务器配置方式

修改当前站点Nginx的配置如下。其中端口号必须是一个比较独特的端口号&#xff0c;比如8001。这样可以跟别的项目区分开来。域名使用0.0.0.0。 server {listen 80;listen 8001;server_name zfmap.cc 0.0.0.0;假设你电脑端的ip地址是192.168.1.101,那么你的手机与你的电脑连在同…

【算法】计数排序、桶排序、基数排序

算法系列八&#xff1a;非比较排序 一、计数排序 1.实现 1.1步骤 1.2代码 2.性质 2.1稳定性 2.1.1从前往后前始版&#xff1a; 2.1.2从后往前末始版&#xff1a; 2.2复杂度 2.2.1时间复杂度 2.2.2空间复杂度 二、桶排序 1.实现 1.1步骤 1.2代码 2.稳定性 三、…

JDK版本与Spring Boot版本之间对应关系

JDK&#xff08;Java Development Kit&#xff09;版本与Spring Boot版本之间存在一定的对应关系&#xff0c;选择合适的搭配对项目的稳定性、性能及功能实现至关重要&#xff0c;以下是详细介绍&#xff1a; 主要版本对应关系 Spring Boot版本发布日期支持的JDK版本备注3.2.…

如何检测Python项目哪些依赖库没有使用

要检测Python项目中哪些依赖库未被使用&#xff0c;可以采用以下方法&#xff1a; 1. 使用静态分析工具 vulture&#xff1a;静态分析工具&#xff0c;检测未使用的代码和导入 pip install vulture vulture your_project/pyflakes&#xff1a;检查未使用的导入语句 pip ins…

【智能指针】—— 我与C++的不解之缘(三十三)

一、智能指针的使用 还记得&#xff0c;在异常学习的时候&#xff0c;我们分析出了一个问题 double Divide(int x, int y) {if (y 0){throw string("the y is zero");}return (double)x / double(y); } void test(int x, int y) {int* arr new int[10];Divide(x,…

Hadoop+Spark 笔记 2025/4/21

读书笔记 定义 1. 大数据&#xff08;Big Data&#xff09; - 指传统数据处理工具难以处理的海量、高速、多样的数据集合&#xff0c;通常具备3V特性&#xff08;Volume体量大、Velocity速度快、Variety多样性&#xff09;。扩展后还包括Veracity&#xff08;真实性&#x…

femap许可不足如何解决

在复杂的工程仿真领域&#xff0c;Femap以其强大的功能和广泛的应用场景而备受青睐。然而&#xff0c;随着用户需求的增长和项目规模的扩大&#xff0c;Femap许可不足的问题逐渐凸显&#xff0c;成为了许多工程师和团队面临的挑战。本文将为您详细解析Femap许可不足的原因&…

【Microsoft Store 中的软件推荐】

目录&#xff1a; &#x1f600; TranslucentTB&#x1f600; Snipaste&#x1f600; Watt Toolkit&#x1f600; NVIDIA Control Panel&#x1f600; Typedown 微软应用商店中的软件会直接安装在C盘&#xff0c;所以&#xff0c;下面分享的这些是即超级好用&#xff0c;又占用…

AOSP Android14 Launcher3——RecentsView最近任务数据加载

最近任务是Launcher中的一个重要的功能&#xff0c;显示用户最近使用的应用&#xff0c;并可以快速切换到其中的应用&#xff1b;用户可以通过底部上滑停顿进入最近任务&#xff0c;也可以在第三方应用底部上滑进最近任务。 这两种场景之前的博客也介绍过&#xff0c;本文就不…

Flink介绍——实时计算核心论文之Flink论文

引入 通过前面的文章&#xff0c;我们梳理了大数据流计算的核心发展脉络&#xff1a; S4论文详解S4论文总结Storm论文详解Storm论文总结Kafka论文详解Kafka论文总结MillWheel论文详解MillWheel论文总结Dataflow论文详解Dataflow论文总结 而我们专栏的主角Flink正是站在前人的…

极狐GitLab CEO 柳钢受邀出席 2025 全球机器学习技术大会

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 2025 年 4 月 18 日至 19 日&#xff0c;2025 全球机器学习技术大会&#xff08;ML-Summit 2025&#xff09;在上海隆重举行。…

Linux Sed 深度解析:从日志清洗到 K8s 等12个高频场景

看图猜诗&#xff0c;你有任何想法都可以在评论区留言哦~ 摘要&#xff1a;Sed&#xff08;Stream Editor&#xff09;作为 Linux 三剑客之一&#xff0c;凭借其流式处理与正则表达式能力&#xff0c;成为运维场景中文本批处理的核心工具。本文聚焦生产环境高频需求&#xff…

C++ STL 容器简介(蓝桥杯适用精简版)

C的万能头文件是&#xff1a; #include <bits/stdc.h> 一、常用 STL 容器 1.vector&#xff08;动态数组&#xff09; #include<iostream> #include<string> #include <vector> #include <algorithm> // 包含排序所需的头文件 using namespa…

Java语言的进化:JDK的未来版本

作为一名Java开发者&#xff0c;我们正处在一个令人兴奋的时代&#xff01;Java语言正在以前所未有的速度进化&#xff0c;每个新版本都带来令人惊喜的特性。让我们一起探索JDK未来版本的发展方向&#xff0c;看看Java将如何继续领跑编程语言界&#xff01;&#x1f4aa; &…

不要使用Round函数保留小数位了

不要使用Round函数保留小数位了 如果你表格不需要保留公式&#xff0c;那么就不要使用Round函数保留小数位了。用Excel工作圈插件&#xff0c;可以轻松以数值形式保留小数位&#xff0c;且支持合并单元格、不连贯区域快速处理。 如下图&#xff0c;有文本&#xff0c;有跨行合并…

【C++】入门基础【下】

目录 一、缺省参数二、函数重载1. 函数类型不同2. 参数个数不同3、函数类型顺序不同 三、引用1、引用的概念和定义2、引用的功能2.1 功能1&#xff1a; 做函数形参&#xff0c;修改形参影响实参2.2 功能2&#xff1a; 做函数形参&#xff0c;减少拷贝&#xff0c;提高效率2.3 功…

git比较不同分支的不同提交文件差异

背景&#xff1a;只想比较某2个分支的某2次提交的差异&#xff0c;不需要带上父提交。 以commitA为基准&#xff0c;用commitB去比较差异 直接上代码&#xff1a; commitAxxxx1 commitBxxxx2 outputFile"output.txt"# 获取与第一个父提交的文件列表 filesA$(git di…

Linux内核之struct pt_regs结构

前沿 项目开发最近进行系统hook功能实现相关业务&#xff0c;主要在centos7和8系列环境开发下关功能。调研了相关知识点&#xff0c;发现在系统7和8上内核版本差别比较大&#xff0c;7-3.10.x系列版本&#xff0c;8-4.18.x系列版本。依据两个系统的内核情况根对应的内核符号表进…

《从混乱到有序:ArkUI项目文件结构改造指南》

在ArkUI开发的广袤天地里&#xff0c;构建一个清晰、有序的文件结构&#xff0c;是打造优质应用的关键。一个合理的文件结构&#xff0c;就像为开发者精心绘制的地图&#xff0c;在项目的各个阶段&#xff0c;都能提供明确的指引&#xff0c;让开发过程顺畅无阻。今天&#xff…