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

news2024/11/16 6:36:50

请添加图片描述

✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: 三十天精通 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对象,该对象包含nameageaddress三个属性。由于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属性限定为一个泛型类型为stringUser对象。

setup()函数中,我们从user属性对象中取出了它的namedata属性,并将它们暴露给模板。

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);
  },
  ...
})

在这里插入图片描述

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

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

相关文章

Golang每日一练(leetDay0055)

目录 159.至多包含两个不同字符的最长子串 Longest-substring-with-at-most-two-distinct-characters &#x1f31f;&#x1f31f; 160. 相交链表 Intersection-of-two-linked-lists &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 …

Stable Diffusion +ChatGPT+文本转语音+剪映制作视频

目录 chatgpt免费体验入口网址 模型下载 huggingface.co civitai.com 使用Deliberate模型案例 StableDeffusion做的图片&#xff0c;chatGPT出的文案&#xff0c;微软文本转语音配的音&#xff0c;使用剪映做的视频 chatgpt免费体验入口网址 http://chat.xutongbao.top …

【Java数据结构】顺序表、队列、栈、链表、哈希表

顺序表 定义 存放数据使用数组但是可以编写一些额外的操作来强化为线性表&#xff0c;底层依然采用顺序存储实现的线性表&#xff0c;称为顺序表 代码实现 创建类型 先定义一个新的类型 public class ArrayList<E> {int capacity 10; //顺序表的最大容量int size …

UNIX环境高级编程——信号

10.1 引言 信号是软件中断&#xff1b;信号提供了一种处理异步事件的方法。 10.2 信号概念 每个信号都有一个名字&#xff0c;这些名字都以3个字符SIG开头&#xff1b;在头文件<signal.h>中&#xff0c;信号名都被定义为正整数常量&#xff08;信号编号&#xff09;&a…

架构设计-高性能篇

大家好&#xff0c;我是易安&#xff01;今天我们谈一谈架构设计中的高性能架构涉及到的底层思想。本文分为缓存架构&#xff0c;单服务器高性能模型&#xff0c;集群下的高性能模型三个部分&#xff0c;内容很干&#xff0c;希望你仔细阅读。 高性能缓存架构 在某些复杂的业务…

代码审计笔记之java多环境变量设置

在做java代码审计时&#xff0c;为了要成功运行目标环境&#xff0c;时长要对于jdk版进行切换&#xff0c;且在装多个jdk时还时长会遇到安装配置后环境变量不生效的情况&#xff0c;下文介绍&#xff1b; 1、为什么安装了新的jdk&#xff0c;有的时候环境变量中的jdk版本确还是…

如何设计出好的测试用例?

软件测试培训之如何设计出好的测试用例? 一句话概括&#xff1a;对被测软件的需求有深入的理解。 深入理解被测软件需求的最好方法是&#xff0c;测试工程师在需求分析和设计阶段就开始介入&#xff0c;因为这个阶段是理解和掌握软件的原始业务需求的最好时机。 只有真正理解了…

【VAR模型 | 时间序列】帮助文档:VAR模型的引入和Python实践(含源代码)

向量自回归 (VAR) 是一种随机过程模型&#xff0c;用于捕获多个时间序列之间的线性相互依赖性。 VAR 模型通过允许多个进化变量来概括单变量自回归模型&#xff08;AR 模型&#xff09;。 VAR 中的所有变量都以相同的方式进入模型&#xff1a;每个变量都有一个方程式&#xff…

轻松掌握在已有K8s环境上安装KubeSphere

官方文档地址&#xff1a;https://kubesphere.io/zh/docs/v3.3/quick-start/minimal-kubesphere-on-k8s/ 1、基于已有K8s环境上安装KubeSphere 1、前置环境 1、安装nfs及动态存储类PV/PVC 安装默认存储类型&#xff0c;这里使用nfs&#xff0c;关于nfs的安装在PV/PVC的文章…

出道的第八年,依然AI着......

今天&#xff0c;是数说故事8周岁的生日 8年&#xff0c;和您一起走过2,922天 8年&#xff0c;我们对AI的探索从未停止 8年&#xff0c;我们将数据的热爱进行到底 因为热“AI” 我们与您的故事有了连接 8年的连接&#xff0c;我们与您也擦出了无数花火 我们将每一个闪烁的…

Optional参数类使用

目录 介绍 使用 常用方法 是否为空 对象比较 Optional 是一个对象容器&#xff0c;具有以下两个特点&#xff1a; 使用 1. 创建 2. 获取&#xff1a; 3. 判断&#xff1a; 4. 过滤&#xff1a; 5. 映射&#xff1a; 介绍 在使用值判断的时候使用方便 使用 import j…

linux系统TP-ti,tsc2046外设调试

一、整体调试思路 tp外设属于比较常见且比较简单的外设&#xff0c;今天以ti,tsc2046这款为例简述下tp外设的调试。 整体思路 1、配置设备树----驱动调试的device部分 2、tp驱动编译及匹配—driver部分 3、驱动整体调试 二、配置设备树 对于ti,tsc2046我们可以参考内核Docum…

复杂美科技多项区块链技术产品被纳入《2021-2022区块链产业图谱》区块链蓝皮书

2022年9月3日&#xff0c;由中国社会科学院社会科学文献出版社、北京金融科技产业联盟指导&#xff0c;北京区块链技术应用协会&#xff08;BBAA&#xff09;主办的 “Web 3.0发展趋势高峰论坛暨2022元宇宙、区块链、金融科技蓝皮书发布会” 在服贸会上成功举办。 大会隆重发布…

身份鉴别解读与技术实现分析(1)

6.1.4.1 身份鉴别 本项要求包括: a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换; b) 应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施 在等级保护体系中,级别越高…

数字时代下网络安全的重要性

在数字时代&#xff0c;网络安全比以往任何时候都更加重要。 随着我们越来越依赖技术来存储和传输敏感信息&#xff0c;网络攻击的风险也在增加。网络攻击可能来自世界任何地方&#xff0c;对个人和企业都可能是毁灭性的。 AkamaiTechnologies首席安全官BoazGelbord在最近的一…

【YOLO系列】YOLOv7论文超详细解读(翻译 +学习笔记)

前言 终于读到传说中的YOLOv7了~≖‿≖✧ 这篇是在美团的v6出来不到一个月就高调登场&#xff0c;作者还是我们熟悉的AB大神&#xff08;对&#xff0c;就是v4那个&#xff09;&#xff0c;读起来又是“熟悉”的感觉&#xff08;贯穿了我的整个五一假期&#xff08;╯&#x…

Vue组件设计-多列表拖拽交换排序

在前端开发中&#xff0c;拖拽排序是一种提升用户体验非常好的方式&#xff0c;常见的场景有单列表拖拽排序&#xff0c;多列表拖拽交换排序&#xff0c;比如以下这种效果&#xff1a; 下面将以这种效果为例&#xff0c;设计一个组件。 1. 安装所需依赖 npm install vuedragg…

多模态的过渡态——latent modal

背景&#xff1a; 随着大模型的推进&#xff0c;单模态的大模型已经无法很好的满足现实工作的需要。很多科研团队和机构开始多模态的研究&#xff0c;多模态的几种机构在前面的文章已经介绍过&#xff0c;这部分不做过多介绍。最理想的多模态应该就是没有模态&#xff0c;单一…

持续集成/持续交付——JenkinsFile详细使用教程

JenkinsFile详细使用教程 一、BlueOcean1、BlueOcean 概念2、BlueOcean 特性3、BlueOcean 安装 二、Pipeline 简介1、Jenkins Pipeline 概念2、Jenkinsfile 语法类型&#xff1a;3、采用Jenkins 任务页面输入a. Jenkins中创建一个 pipeline 任务b. Definition 中选择 Pipeline …

电脑提示msvcp140.dll丢失的解决方法,msvcp140.dll丢失修复教程

msvcp140.dll是Microsoft Visual C Redistributable所需的一个动态链接库文件&#xff0c;它包含了Visual C运行库中的一些函数和类库。这个文件通常出现在Windows操作系统中&#xff0c;用于支持使用Visual C编写的程序的正常运行。如果系统缺少或损坏了这个文件&#xff0c;可…