当前位置: 首页 > news >正文

Vue.js 与 TypeScript(1) :项目配置、props标注类型、emits标注类型

        像 TypeScript 这样的类型系统可以在编译时通过静态分析检测出很多常见错误。这减少了生产环境中的运行时错误,也让我们在重构大型项目的时候更有信心。通过 IDE 中基于类型的自动补全,TypeScript 还改善了开发体验和效率。

一、项目配置

        在使用 npm create vue@lates t创建项目时有是否添加typescript选项。

        如果没有在创建项目时添加也可以用下面的命令在已有的项目中添加:

  • npm install -D typescript 最新的稳定版本
  • tsc --init生成tsconfig.json文件

        在tsconfig.json配置文件中添加配置避免使用import时报错问题:

{"compilerOptions": {/* 这里省略了其他配置*/"noImplicitAny": false,"allowJs": true,"baseUrl": "src","paths": {"@/*": ["./*"],"@": ["./"]}},// include也需要配置以下:"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"exclude": ["node_modules"]
}

二、为组件的 props 标注类型

        为子组件的属性指定类型:

<script setup lang="ts">
const props = defineProps({foo: {type: String, required: true},bar: Number
})
</script><template>{{ foo }} - {{ bar }}
</template>

        在父组件中使用:

<script lang="ts" setup>
import TypeScript from "@/components/TypeScript.vue";
import {ref} from "vue";
// 这里不是数值类型将会报错
const number = ref(0);
</script><template><type-script foo="A" :bar="number"></type-script>
</template>

        这被称之为“运行时声明”,因为传递给 defineProps() 的参数会作为运行时的 props 选项使用。然而,通过泛型参数来定义 props 的类型通常更直接:

<script setup lang="ts">
const props = defineProps<{foo: stringbar?: number
}>()
</script>

        这被称之为“基于类型的声明”。编译器会尽可能地尝试根据类型参数推导出等价的运行时选项。在这种场景下,我们第二个例子中编译出的运行时选项和第一个是完全一致的。

        基于类型的声明或者运行时声明可以择一使用,但是不能同时使用。我们也可以将 props 的类型移入一个单独的接口中:

<script setup lang="ts">
interface Props {foo: stringbar?: number
}const props = defineProps<Props>()
</script>

        这同样适用于 Props 从另一个源文件中导入的情况。该功能要求 TypeScript 作为 Vue 的一个 peer dependency。

<script setup lang="ts">
import type { Props } from './foo'const props = defineProps<Props>()
</script>

1、Props 解构默认值

        当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。这可以通过 withDefaults 编译器宏解决:

<script setup lang="ts">
export interface Props {msg?: stringlabels?: string[]
}// 为 Props提供默认值
const props = withDefaults(defineProps<Props>(), {msg: 'hello',labels: () => ['one', 'two']
})
</script><template>{{ msg }} - {{ labels }}
</template>

        这将被编译为等效的运行时 props default 选项。此外,withDefaults 帮助程序为默认值提供类型检查,并确保返回的 props 类型删除了已声明默认值的属性的可选标志。

2、非 <script setup> 场景下

        如果没有使用 <script setup>,那么为了开启 props 的类型推导,必须使用 defineComponent()。传入 setup() 的 props 对象类型是从 props 选项中推导而来。

import { defineComponent } from 'vue'export default defineComponent({props: {message: String},setup(props) {props.message // <-- 类型:string}
})

3、复杂的 prop 类型

        通过基于类型的声明,一个 prop 可以像使用其他任何类型一样使用一个复杂类型:

<script setup lang="ts">
interface Book {title: stringauthor: stringyear: number
}const props = defineProps<{book: Book
}>()
</script>

        对于运行时声明,我们可以使用 PropType 工具类型:

<script setup lang="ts">
import type { PropType } from 'vue'interface Book {title: stringauthor: stringyear: number
}const props = defineProps({book: Object as PropType<Book>
})
</script><template>{{ book }}
</template>

        在父组件中使用:

<script lang="ts" setup>
import TypeScript from "@/components/TypeScript.vue";
import {reactive} from "vue";
// 会进行类型检查
const book = reactive({title: "A",author: "B",year: 2024
});
</script><template><type-script :book="book"></type-script>
</template>

三、为组件的 emits 标注类型

        在 <script setup> 中,emit 函数的类型标注也可以通过运行时声明或是类型声明进行:

<script setup lang="ts">
/*
// 运行时
const emit = defineEmits(['change', 'update'])// 基于选项
const emit = defineEmits({change: (id: number) => {// 返回 `true` 或 `false`// 表明验证通过或失败},update: (value: string) => {// 返回 `true` 或 `false`// 表明验证通过或失败}
})// 基于类型
const emit = defineEmits<{(e: 'change', id: number): void(e: 'update', value: string): void
}>()
*/
// 3.3+: 可选的、更简洁的语法
const emit = defineEmits<{change: [id: number]update: [value: string]
}>()
</script><template><button @click="$emit('change',1)">按钮1</button><button @click="$emit('update','a')">按钮2</button>
</template>

        在父组件中使用:

<script lang="ts" setup>
import TypeScript from "@/components/TypeScript.vue";
// 点击按钮1触发,获取传递的参数
function change(args) {console.log(args);
}
// 点击按钮2触发,获取传递的参数
function update(args) {console.log(args);
}</script><template><type-script @change="change" @update="update"></type-script>
</template>

        类型参数可以是以下的一种:

  1. 一个可调用的函数类型,但是写作一个包含调用签名的类型字面量。它将被用作返回的 emit 函数的类型。
  2. 一个类型字面量,其中键是事件名称,值是数组或元组类型,表示事件的附加接受参数。上面的示例使用了具名元组,因此每个参数都可以有一个显式的名称。

        我们可以看到,基于类型的声明使我们可以对所触发事件的类型进行更细粒度的控制。若没有使用 <script setup>defineComponent() 也可以根据 emits 选项推导暴露在 setup 上下文中的 emit 函数的类型:

import { defineComponent } from 'vue'export default defineComponent({emits: ['change'],setup(props, { emit }) {emit('change') // <-- 类型检查 / 自动补全}
})

相关文章:

Vue.js 与 TypeScript(1) :项目配置、props标注类型、emits标注类型

像 TypeScript 这样的类型系统可以在编译时通过静态分析检测出很多常见错误。这减少了生产环境中的运行时错误&#xff0c;也让我们在重构大型项目的时候更有信心。通过 IDE 中基于类型的自动补全&#xff0c;TypeScript 还改善了开发体验和效率。 一、项目配置 在使用 npm cr…...

【考试100】安全员B证《建设工程安全生产技术》单选题

​ 题库来源&#xff1a;考试100 【考试100】安全员B证《建设工程安全生产技术》单选题 1&#xff0e;在悬空部位作业时&#xff0c;操作人员应&#xff08; &#xff09; A.遵守操作规定 B.进行安全技术交底 C.戴好安全帽 D.系好安全带 【考试100答案】&#xff1a;D…...

linux进阶的一些操作以及知识点------习题集(实践)

请创建以你姓名全拼的用户luwenhua&#xff0c;将其设置为免密登录&#xff0c;切换到luwenhua用户&#xff0c;打开终端&#xff0c;完成以下操作 &#xff08;一&#xff09;bash脚本基础练习 1&#xff09;第一题&#xff1a;请在终端里定义两个用户变量num120&#xff0c…...

提莫攻击 ---- 模拟算法

题目链接 题目: 分析: 如果两次攻击的时间差是>中毒的持续时间duration, 那么第一次攻击的中毒时间就是duration如果两次攻击的时间差是< 中毒的持续时间duration, 那么第一次攻击的持续时间就是这个时间差假设攻击了n次, 那么我们从第一次攻击开始计算时间差, 那么当我…...

SpringBootWeb 篇-深入了解 Spring 异常处理、事务管理和配置文件参数配置化、yml 配置文件

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 配置文件 1.1 yml 配置文件 1.2 参数配置化 1.2.1 使用 Value 注解注入单个配置参数 1.2.2 使用 ConfigurationProperties 注解将一组相关配置参数注入到一个类中…...

重学java 55. 集合 Set接口

我救自己万万次&#xff0c;铮铮劲草&#xff0c;绝不动摇 —— 24.6.2 一、Set集合介绍 Set和Map密切相关的 Map的遍历需要先变成单列集合&#xff0c;只能变成set集合 二、HashSet集合的介绍和使用 1.概述 HashSet是Set接口的实现类 2.特点 a、元素唯一 b、元素无序 c、无索引…...

spring项目修改时间格式

一、配置方式 在application.yml上添加 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8 二、注解方式 1、添加依赖 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId&…...

每周统计-20240531

用于测试程序的稳定性&#xff1a; 龙虎榜&#xff1a; 成交额&#xff1a; 封成比&#xff1a; 收盘前放量&#xff1a; 开盘抢筹&#xff1a; 封单额&#xff1a;...

【工具】探索 DOU:每用户数据使用量

缘分让我们相遇乱世以外 命运却要我们危难中相爱 也许未来遥远在光年之外 我愿守候未知里为你等待 我没想到为了你我能疯狂到 山崩海啸没有你根本不想逃 我的大脑为了你已经疯狂到 脉搏心跳没有你根本不重要 &#x1f3b5; 邓紫棋《光年之外》 什么是 DOU…...

JVM之垃圾判断的详细解析

垃圾判断 垃圾介绍 垃圾&#xff1a;如果一个或多个对象没有任何的引用指向它了&#xff0c;那么这个对象现在就是垃圾 作用&#xff1a;释放没用的对象&#xff0c;清除内存里的记录碎片&#xff0c;碎片整理将所占用的堆内存移到堆的一端&#xff0c;以便 JVM 将整理出的内…...

07- Redis 中的 HyperLogLog 数据类型和应用场景

1. 介绍 Redis HyperLogLog 是 Redis 2.8.9 版本新增的数据类型&#xff0c;是一种用于【统计基数】的数据集合类型&#xff0c;基数统计就是指统计一个集合中不重复的元素个数。但要注意&#xff0c;HyperLogLog 的统计规则是基于概率完成的&#xff0c;不是非常准确&#xf…...

jenkins应用2-freestyle-job

1.jenkins应用 1.jenkins构建的流程 1.使用git参数化构建&#xff0c;用标签区分版本 2.git 拉取gitlab远程仓库代码 3.maven打包项目 4.sonarqube经行代码质量检测 5.自定义制作镜像发送到远程仓库harbor 6.在远程服务器上拉取代码启动容器 这个是构建的整个过程和步骤…...

K210视觉识别模块学习笔记1:第一个串口程序_程序烧录与开机启动

今日开始学习K210视觉识别模块:简单的认识与串口程序 亚博智能的K210视觉识别模块...... 固件库版本: canmv_yahboom_v2.1.1.bin 既然K210作为一个视觉识别外设模块来使用&#xff0c;我认为第一个程序 就没必要学点灯之类的了&#xff0c;直接学习串口如何配置开始为妥&…...

[数据集][目标检测]脑溢血检测数据集VOC+YOLO格式767张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;767 标注数量(xml文件个数)&#xff1a;767 标注数量(txt文件个数)&#xff1a;767 标注类别…...

如何借VR之手,让展厅互动更精彩?

VR虚拟现实技术以其卓越的沉浸式体验为特点&#xff0c;引领用户踏入一个全新的虚拟世界&#xff0c;正因如此&#xff0c;它开始被广泛应用于展厅、商业等多个领域。那么&#xff0c;今天&#xff0c;让我们就来了解一下这种技术是如何为展厅带来精彩互动体验的吧&#xff01;…...

微信小程序如何使用地图

微信小程序使用地图功能时&#xff0c;主要涉及到地图组件的引入、配置、以及相关的API调用。以下是一个详细的使用指南&#xff1a; 1. 引入地图组件 在微信小程序的.wxml文件中&#xff0c;通过<map>标签引入地图组件。你可以设置地图的经纬度、缩放级别、控件等属性…...

力扣 287. 寻找重复数

给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 &#xff0c;返回 这个重复的数 。你设计的解决方案必须 不修改 数组 nums 且只用常量…...

怎样清理Mac存储空间 苹果电脑内存不够用怎么办 苹果电脑内存满了怎么清理

在使用 Mac 电脑的过程中&#xff0c;用户经常会遇到磁盘空间不足的困扰&#xff0c;这时候就需要寻找有效的方法来清理苹果电脑内存了。 清理Mac存储空间可以通过多种方法进行&#xff0c;以确保你的Mac能够高效运行并释放宝贵的存储空间。以下是一些有效的清理和优化方法&am…...

网络遗忘权的实现方法

网络遗忘权的实现方法 目录 从禁书说起 从销毁硬件信息的方法得到的启示 现在网络遗忘权的实现方法 从禁书说起 古代有禁书的需求,直接的方法就是贴出告示,强行收缴,然后付之一炬. 这个方法的问题在于只要有一个人敢冒死藏书,再次手抄或者是印刷,就 会让之前的禁书努力,付…...

【Python内功心法】:深挖内置函数,释放语言潜能

文章目录 &#x1f680;一、常见内置函数&#x1f308;二、高级内置函数⭐1. enumerate函数&#x1f44a;2. eval函数❤️3. exec函数&#x1f4a5;4. eval与exec 中 globals与locals如何用☔4-1 globals 参数&#x1f3ac;4-2 locals 参数 ❤️5. filter函数&#x1f44a;6. z…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...