【三十天精通Vue 3】第二十六天 Vue3 与 TypeScript 最佳实践

✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: 三十天精通 Vue 3
文章目录
- 引言
- 一、为什么使用TypeScript?
- 二、Vue 3和TypeScript的基础
- 2.1 安装TypeScript
- 2.2 配置TypeScript
- 2.3 Vue 3中使用TypeScript
- 三、Vue 3和TypeScript的进阶
- 3.1 类型检查
- 3.2 接口
- 3.3 枚举
- 3.4 泛型
- 3.5 装饰器
- 3.6 Mixins
- 四、Vue 3和TypeScript的最佳实践
- 4.1 单文件组件
- 4.2 组件通信
- 4.3 组件 Props
- 4.4 事件处理
- 4.5 生命周期
- 4.6 Vuex和TypeScript
- 4.7 Axios和TypeScript
引言
Vue.js 3.x是一种流行的JavaScript框架,它允许我们使用模板语法来快速开发应用程序、组件化和封装,同时还提供了高效的响应式数据绑定、组件通信等众多特性。相对于其前身Vue.js 2.x,Vue 3.x进一步增强了TypeScript的支持,使我们可以更容易地将TypeScript与Vue.js结合使用,以提高我们的代码质量、可维护性和开发效率。
本篇文章将从为什么使用TypeScript、TypeScript的优势、Vue 3和TypeScript的基础、Vue 3和TypeScript的进阶、以及Vue 3和TypeScript的最佳实践等几个方面介绍如何使用Vue 3和TypeScript进行开发。
一、为什么使用TypeScript?
TypeScript相比于JavaScript,有如下的优点:
1.静态类型检查:使用静态类型检查可以帮助我们在编码时发现一些隐藏的类型错误,从而在开发周期的早期就能够进行修改,避免在其他环节引入更严重的bug。
2.代码提示:使用TypeScript,开发者在写代码的时候会得到更全面、更准确的代码提示,这对开发效率和代码编写的准确性都有积极的影响。
3.代码可读性提高:使用TypeScript可以明确地表达代码中的数据类型、接口和方法的类型等信息,这能够提高代码的可读性。
4.文档自动生成:TypeScript可以根据代码生成文档,更加方便地为其他的开发者提供使用帮助。
5.维护成本降低:代码中的类型和接口可以帮助开发团队理解整个代码库,降低了维护代码的成本。
二、Vue 3和TypeScript的基础
在开始使用Vue.js 3和TypeScript编写代码之前,需要先安装TypeScript,配置TypeScript环境。
2.1 安装TypeScript
TypeScript的安装比较简单,可以使用npm工具进行安装。执行以下命令即可完成TypeScript的安装:
npm install -g typescript
2.2 配置TypeScript
在安装了TypeScript之后,我们需要进行一些简单的TypeScript配置,以便在开发Vue 3应用程序时使用。
TypeScript的配置文件为tsconfig.json,我们需要在Vue 3项目的根目录下添加一个tsconfig.json文件。例如,在默认的Vue 3项目文件夹中,该文件的路径为./tsconfig.json。我们可以通过以下的命令来创建tsconfig.json文件:
tsc --init
这个命令将生成一个包含默认设置的tsconfig.json文件。我们可以针对具体的项目,根据需要进行一些简单的编辑,比如指定目标JavaScript版本、配置编译选项等等。
2.3 Vue 3中使用TypeScript
默认情况下,Vue 3项目使用单文件组件(SFC)来管理其组件,而这些组件可以通过业务逻辑脚本文件中的JavaScript代码来实现。如果我们要使用TypeScript编写业务逻辑,就需要将.js文件转换为.ts文件。
我们可以在.vue文件中使用TypeScript,只需要在<script>标记中添加lang="ts"属性即可。下面是一个示例:
<template><div>{{ message }}</div>
</template><script lang="ts">
import { defineComponent } from 'vue';export default defineComponent({name: 'HelloWorld',props: {message: String},setup(props) {return {message: props.message};}
});
</script>
在这个例子中,我们可以看到<script>标记中的lang属性设置为"ts",这是告诉Vue 3,SFC文件中的脚本代码使用TypeScript编写。
三、Vue 3和TypeScript的进阶
3.1 类型检查
TypeScript最重要的一个特性就是类型检查,它可以帮助我们在代码编写过程中避免许多潜在的类型错误。在Vue 3中,我们也可以使用类型检查来增加代码的可维护性和健壮性。
下面是一个使用类型检查的示例:
import { defineComponent, PropType } from 'vue';interface User {name: string;age: number;address: string;
}export default defineComponent({name: 'UserCard',props: {user: {type: Object as PropType<User>,required: true}},setup(props) {const { user } = props;const isValid = (data: User): boolean => {return (data && data.name && data.age && data.address);};return {user: isValid(user) ? user : null};}
});
在这个示例中,我们使用了一个名为User的接口表示一个User对象,该对象包含name、age和address三个属性。由于props中的user是一个Object类型的值,我们需要使用PropType将其类型限定为User。
在setup()函数中,我们定义了一个名为isValid()的函数,用于检查传入的user对象是否合法,如果合法则返回该对象,否则返回null。这个函数会在组件的user属性被初始化时被调用,在组件的其它位置,也可以使用isValid()函数对任意User对象进行检查。
3.2 接口
TypeScript中的接口可以用来描述一个对象的形状(也就是属性、方法的集合),从而可以在多个地方进行类型检查。Vue 3中组件的props和emit选项可以使用接口来描述其类型。
下面是一个示例:
import { defineComponent } from 'vue';interface Props {message: string;
}interface Emit {change: (value: string) => void;
}export default defineComponent({name: 'HelloWorld',props: {message: {type: String,required: true}},emits: ['change'],setup(props, { emit }) {const handleChange = (event: Event) => {const value = event.target.value;emit('change', value);};return {handleChange};}
});
在这个示例中,我们定义了一个名为Props的接口,用于描述HelloWorld组件的props对象的形状,该对象包括一个名为message的字符串属性。
我们还定义了一个名为Emit的接口,用于描述HelloWorld组件的emit对象的形状,该对象包括一个名为change的事件。
在组件中,我们使用了Props接口来描述组件中的message属性,使用了Emit接口来描述组件的emit对象。我们还在组件中定义了一个名为handleChange()的函数,用于将输入框中的值传递给父组件,该函数会在输入框的值发生变化时被调用,并触发change事件。
3.3 枚举
TypeScript中的枚举可以方便地为一组相关的常量赋予一组有意义的名字,从而增加代码的可读性。Vue 3中也可以使用枚举来描述一些基于数字或字符串的常量。
下面是一个枚举的示例:
import { defineComponent } from 'vue';enum OrderStatus {Unpaid = 'unpaid',Paid = 'paid',Shipped = 'shipped',Delivered = 'delivered'
}export default defineComponent({name: 'OrderList',setup() {const orderStatusToString = (status: OrderStatus) => {switch (status) {case OrderStatus.Unpaid:return '待付款';case OrderStatus.Paid:return '已付款';case OrderStatus.Shipped:return '已发货';case OrderStatus.Delivered:return '已签收';}};return {orderStatusToString};}
});
在这个示例中,我们定义了一个名为OrderStatus的枚举,用于描述订单状态的四个值。我们还定义了一个名为orderStatusToString()的函数,用于将枚举值转换为相应的中文订单状态名称。
在组件的setup()函数中,我们通过return语句将orderStatusToString()函数暴露给模板。
3.4 泛型
TypeScript中的泛型可以方便地为函数或类中的类型参数添加类型约束,从而提供更加灵活和安全的泛型编程能力。Vue 3中的组件props和emit属性也可以使用泛型来描述其类型。
下面是一个示例:
import { defineComponent, PropType } from 'vue';interface User<T> {id: number;name: string;age: number;data: T;
}export default defineComponent({name: 'UserCard',props: {user: {type: Object as PropType<User<string>>,required: true}},setup(props) {const { user } = props;return {userName: user.name,userData: user.data};}
});
在这个示例中,我们定义了一个名为User的泛型接口,其中类型参数T表示data属性的类型。
在组件的props中,我们使用了PropType来将user属性限定为一个泛型类型为string的User对象。
在setup()函数中,我们从user属性对象中取出了它的name和data属性,并将它们暴露给模板。
3.5 装饰器
TypeScript中的装饰器是一种特殊的语法,可以用来修饰类、方法、属性和参数等,从而添加额外功能和约束。Vue 3支持使用装饰器来修饰组件、属性和方法等。常用的装饰器包括@Component、@Prop、@Emit、@Watch等。
下面是一个示例:
import { defineComponent } from 'vue';@Component
export default class HelloWorld extends Vue {@Prop({ type: String, required: true })message!: string;@Emit()handleClick() {console.log('click');}@Watch('message')handleWatch(newVal: string, oldVal: string) {console.log(`message has been changed from ${oldVal} to ${newVal}`);}
};
在这个示例中,我们使用了三个常用的装饰器:
@Component:用于修饰Vue 3组件类,将类声明为一个Vue组件。@Prop:用于修饰类中的属性,将属性声明为Vue组件的prop属性。@Emit:用于修饰类中的方法,将方法标记为发射的自定义事件。@Watch:用于修饰类中的方法,将方法标记为监视的数据变化。
3.6 Mixins
Mixins是一种复用组件逻辑的方式,Vue 3中的Mixins与TypeScript结合使用时需要注意,因为Mixins扩展的属性和方法类型不能添加到子类原有的类型定义中。为了解决这个问题,可以使用交叉类型或者泛型约束。
下面是一个示例:
import { defineComponent } from 'vue';interface Mixin {message: string;showMessage(): void;
}const MyMixin = {data() {return {message: 'Hello Mixin!'};},methods: {showMessage() {console.log(this.message);}}
};export default defineComponent({name: 'HelloWorld',mixins: [MyMixin as Mixin],setup() {const handleClick = () => {this.showMessage();};return {handleClick};}
});
在这个示例中,我们定义了一个名为Mixin的接口,用于描述Vue 3 Mixin中的属性和方法。我们还定义了一个名为MyMixin的Mixins对象,该对象包含一个data对象和methods对象。
在组件中,我们通过将MyMixin对象强制转换为Mixin接口类型并传给mixins选项,使组件可以复用MyMixin中的属性和方法。
最后,我们定义了一个名为handleClick()的函数,该函数会调用showMessage()方法。
四、Vue 3和TypeScript的最佳实践
4.1 单文件组件
在Vue 3和TypeScript中使用单文件组件时,建议在.vue文件中使用
同时,需要注意的是,如果要让Vue 3识别TypeScript文件,需要在项目中安装vue-tsc并且在tsconfig.json中正确配置:
{"compilerOptions": {..."module": "esnext","target": "esnext","jsx": "preserve","sourceMap": true,"strict": true,"esModuleInterop": true,"moduleResolution": "node","types": ["webpack-env","@types/node","@vue/cli-plugin-typescript"],"allowSyntheticDefaultImports": true,"resolveJsonModule": true,"isolatedModules": true,"noImplicitAny": false},"include": ["src/**/*.ts","src/**/*.tsx","src/**/*.vue"],"exclude": ["node_modules"]
}
4.2 组件通信
在Vue 3和TypeScript中,组件之间的通信可以使用props和event进行。
props可以定义组件之间所需的属性,并且可以在组件内部进行类型检查。例如:
interface Props {message: string
}export default defineComponent<Props>({props: {message: {type: String,required: true,},},...
})
event可以定义组件之间所需的事件类型,并且可以在组件内部进行类型检查。例如:
interface CustomEvents {click: () => void;
}export default defineComponent<{}, CustomEvents>({emits: ["click"],...
})
4.3 组件 Props
在Vue 3和TypeScript中,组件的props可以在组件内部进行类型检查,这可以更好地保证组件的健壮性。
例如,在组件定义时,可以使用Props interface定义prop的类型,并在props选项中进行声明。如下所示:
interface Props {message: string
}export default defineComponent<{}, {}, Props>({props: {message: {type: String,required: true,},},...
})
4.4 事件处理
在Vue 3和TypeScript中,事件处理的方式与JavaScript中相同,不需要进行特殊处理。不过为了确保正确性和代码的健壮性,建议定义事件的类型,并在组件的emits选项中进行声明。
例如:
interface CustomEvents {click: () => void;
}export default defineComponent<{}, CustomEvents>({emits: ["click"],...
})
4.5 生命周期
在Vue 3和TypeScript中,生命周期钩子仍然有效,但是需要在组件类型定义时,将使用到的生命周期钩子也进行声明。
例如:
export default defineComponent<{}, {}, {}, {}, {mounted: () => void;updated: () => void;
}>({mounted() {console.log("Mounted!");},updated() {console.log("Updated!");},...
})
4.6 Vuex和TypeScript
在使用Vuex和TypeScript时,需要定义store中的state、mutations和actions等类型,并在组件中使用mapState、mapMutations和mapActions等工具来连接store。
例如,定义store中的state类型:
interface State {count: number
}const store = createStore<State>({state: {count: 0,},...
})
在组件中使用mapState连接store:
import { mapState } from "vuex";
import { State } from "@/store";export default defineComponent({computed: {...mapState<State, "count">(["count"]),},...
})
4.7 Axios和TypeScript
在Vue 3和TypeScript中使用axios,需要安装axios和@types/axios库,并在组件中定义返回类型,并在代码中使用async/await或者Promise等方式来处理异步操作。
例如,在组件中定义一个API请求方法:
import axios, { AxiosResponse } from "axios";interface ResponseData {data: string;
}async function fetchData(): Promise<AxiosResponse<ResponseData>> {return await axios.get("/api/data");
}
在组件中使用async/await调用API请求:
export default defineComponent({async mounted() {const response = await fetchData();console.log(response.data);},...
})

相关文章:
【三十天精通Vue 3】第二十六天 Vue3 与 TypeScript 最佳实践
✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录 引言一、为什么使用TypeScript?二、Vue 3和TypeScript…...
ffmpeg-mov-metadate不识别Bug修复
文章目录 BUG起因类似问题反馈问题解决具体步骤: 阅读过文章ffmpeg命令行解析调试流程记录movenc.c源码分析 BUG起因 在ffmpeg参数默认可识别的metadata参数如下: 具体可见libavformat/movenc.c->mov_write_udta_tag() mov_write_string_metadata(s,…...
(8)(8.6) 引导程序更新
文章目录 前言 1 我在哪里可以下载最新的引导程序? 2 使用任务规划器进行升级...
汽车电路图、原理框图、线束图、元器件布置图的识读技巧与要点
摘要: 想要读懂汽车电路图就必须把电的通路理清楚,即某条线是什么信号,该信号是输入信号、输出信号还是控制信号以及信号起什么作用,在什么条件下有信号,从哪里来,到哪里去。 一、汽车电路图的识读技巧 1.…...
( 数组和矩阵) 667. 优美的排列 II ——【Leetcode每日一题】
❓667. 优美的排列 II 难度:中等 给你两个整数 n 和 k ,请你构造一个答案列表 answer ,该列表应当包含从 1 到 n 的 n 个不同正整数,并同时满足下述条件: 假设该列表是 answer [a1, a2, a3, ... , an] ࿰…...
【python基础语法七】python内置函数和内置模块
内置全局函数 abs 绝对值函数 print(abs(-1)) # 1 print(abs(100)) # 100round 四舍五入 """奇进偶不进(n.5的情况特定发生)""" res round(3.87) # 4 res round(4.51) # 5 # res round(2.5) # 2 # res round(3.5) # 4 res round(6.5) # …...
81. read readline readlines 读取文件的三种方法
81. read readline readlines 读取文件的三种方法 文章目录 81. read readline readlines 读取文件的三种方法1. 读取文件的三种方法2. read方法3. readline方法4. readlines方法5. 代码总结5.1 read方法读取全部内容5.2 readline方法读取一行,返回字符串5.3 readli…...
【社区图书馆】【图书活动第四期】
目录 一、前言 二、作者简介 三、《PyTorch高级机器学习实战》内容简介 四、书目录 一、前言 今天,偶尔逛到csdn社区图书馆,看到有活动 “【图书活动第四期】来一起写书评领实体奖牌红包电子勋章吧!”(活动到今天结束…...
webpack学习指南(上)
构建流程 Webpack 的构建流程可以分为以下几个步骤: 解析配置文件:Webpack 会读取项目中的 webpack.config.js 文件,并解析其中的配置项。 解析入口文件:Webpack 通过配置文件中设置的 entry 入口,递归地解析出所有依…...
刷题记录˃ʍ˂
一、1033. 移动石子直到连续 思路 这道题是一道数学题,它一共分为三种可能 第一种可能为三个石子本来就是连续的时候 第二种可能为最少步数为1的时候,相邻石子不能大于一格 第三种可能为最少步数为2的时候,这时相邻石子大于一格 那么第二…...
Word2vec原理+实战学习笔记(二)
来源:投稿 作者:阿克西 编辑:学姐 前篇:Word2vec原理实战学习笔记(一) 视频链接:https://ai.deepshare.net/detail/p_5ee62f90022ee_zFpnlHXA/6 5 对比模型(论文Model Architectur…...
什么是Java的多线程?
Java的多线程是指在同一时间内,一个程序中同时运行多个线程。每个线程都是一个独立的执行路径,可以独立地执行代码。Java中的多线程机制使得程序可以更高效地利用计算机的多核处理器和CPU时间,从而提高程序的性能和响应能力。 创建和使用Jav…...
“use strict“是什么? 使用它有什么优缺点?
严格模式 - JavaScript | MDN Javascript 严格模式详解 - 阮一峰的网络日志 1、"use strict" 是什么? "use strict" :指定代码在严格条件下执行; 2、 使用 "use strict" 有什么优缺点? ① 严格模式通过抛出错…...
【C++】C++11常用特性总结
哥们哥们,把书读烂,困在爱里是笨蛋! 文章目录 一、统一的列表初始化1.统一的{}初始化2.std::initializer_list类型的初始化 二、简化声明的关键字1.decltype2.auto && nullptr 三、STL中的一些变化1.新增容器:array &…...
泛型——List 优于数组
数组与泛型有很大的不同: 1. 数组是协变的(covariant) 意思是:如果Sub是Super的子类型,则数组类型Sub[] 是数组类型Super[] 的子类型。 2. 泛型是不变的(invariant) 对于任何两种不同的类型Ty…...
JavaScript中对象的定义、引用和复制
JavaScript是一种广泛使用的脚本语言,其设计理念是面向对象的范式。在JavaScript中,对象就是一系列属性的集合,每个属性包含一个名称和一个值。属性的值可以是基本数据类型、对象类型或函数类型,这些类型的值相互之间有着不同的特…...
JavaScript通过函数异常处理来输入圆的半径,输出圆的面积的代码
以下为实现通过函数异常处理来输入圆的半径,输出圆的面积的代码和运行截图 目录 前言 一、通过函数异常处理来输入圆的半径,输出圆的面积 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择,您可以…...
Ubuntu 安装 Mysql
主要内容 本文主要是实现在虚拟机 Ubuntu 18.04 成功安装 MySQL 5.7,并实现远程访问功能,以 windows 下客户端访问虚拟机上的 mysql 数据库。 1. 切换至 root 用户 ,shell 终端指令均执行在 root 用户下 sudo su 2. 安装并设置 mysql 安…...
【五一创作】【Midjourney】Midjourney 连续性人物创作 ② ( 获取大图和 Seed 随机种子 | 通过 seed 随机种子生成类似图像 )
文章目录 一、获取大图和 Seed 随机种子二、通过 seed 种子生成类似图像 一、获取大图和 Seed 随机种子 注意 : 一定是使用 U 按钮 , 在生成的大图的基础上 , 添加 信封 表情 , 才能获取该大图的 Seed 种子编码 ; 在上一篇博客生成图像的基础上 , 点击 U3 获取第三张图的大图 ;…...
分布式事务 --- Seata事务模式、高可用
一、事务模式 1.1、XA模式 XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA 规范 描述了全局的TM与局部的RM之间的接口,几乎所有主流的数据库都对 XA 规范 提供了支持。…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
