尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

TypeScript 核心语法应用 —— Vue 3 中的使用(下)

TypeScript 核心语法应用 —— Vue 3 中的使用(下) 阅读本文你能学到什么如何为组件的props标注类型如何为组件的emits标注类型类型声明文件.d.ts的用途与用法前言上一篇我们学会了 Vue 3 组件内部状态和逻辑的 TS 用法——ref、reactive、computed、事件处理、模板引用等。但一个组件很少是独立存在的组件之间总要传数据。这一篇就来看看在script setup langts中如何用 TS 写出类型安全的组件通信以及类型声明文件怎么用。一、为 props 标注类型defineProps用于声明组件接收的props标注类型后既能保证外部传入的数据类型正确也能在组件内部使用和外部传递时获得代码提示。1.1 基础用法语法definePropsProps类型()示例按钮组件MyButton.vue有两个 prop 参数color类型为string且为必填size类型为string且为可选scriptsetuplangtsinterfaceProps{color:string// 必填size?:string// 可选}constpropsdefinePropsProps()/script使用时必须传递color属性size为可选template!-- ✅ 正确 --MyButtoncolorprimary/!-- ✅ 正确 --MyButtoncolorprimarysizelarge/!-- ❌ 错误缺少必填属性 color --MyButtonsizelarge//template1.2 设置默认值当使用泛型语法声明props时默认值无法直接在类型定义中指定。Vue 提供了两种写法来设置默认值你需要根据 Vue 版本选择合适的方式。方式一响应式 Props 解构Vue 3.5 推荐从 Vue 3.5 开始可以直接在解构时设置默认值代码最简洁scriptsetuplangtsinterfaceProps{msg?:string labels?:string[]}// 直接在解构时赋默认值const{msghello,labels[one,two]}definePropsProps()/script Vue 3.5 对 Props 解构做了增强解构后的变量仍然保持响应式不需要额外处理。方式二withDefaults 编译器宏Vue 3.4 及以下在 Vue 3.4 及更低版本中需要使用withDefaults来设置默认值scriptsetuplangtsinterfaceProps{msg?:string labels?:string[]}constpropswithDefaults(definePropsProps(),{msg:hello,labels:()[one,two]// ⚠️注意 数组、对象需要用函数包装})/scriptwithDefaults不仅提供默认值还会对默认值进行类型检查并自动移除已设默认值属性的可选标志。⚠️ 注意使用withDefaults时数组、对象等引用类型必须用函数返回() []否则所有组件实例会共享同一份数据且 props 不支持解构需直接使用 props.xxx 访问。Vue 3.5 的响应式 Props 解构则无此限制。二、为 emits 标注类型defineEmits用于声明组件可以触发的自定义事件标注类型后既能约束事件名称并给出自动提示避免拼写错误也能约束传参类型防止参数类型错误。2.1 基础用法语法defineEmitsEmits类型()示例子组件触发一个名称为change的事件并且传递一个类型为string的参数scriptsetuplangts// 1. 定义事件类型 EmitsinterfaceEmits{(e:change,state:string):void}// 2. 给泛型参数传参constemitdefineEmitsEmits()constchangeState(){emit(change,pending)// ✅ 类型匹配// emit(change, 123) // ❌ 报错参数类型不匹配// emit(change-event, handled) // ❌ 报错事件名称不匹配}/script2.2 多个事件如果有多个事件可以在Emits接口中继续定义每个事件的参数数量和类型可以不同scriptsetuplangtsinterfaceEmits{(e:change,state:string):void// 1 个参数(e:submit,username:string,password:string):void// 2 个参数(e:update,id:number,data:object,timestamp:number):void// 3 个参数}constemitdefineEmitsEmits()/script 补充Vue 3.3 还支持更简洁的元组语法和上面的调用签名语法效果相同scriptsetuplangtsconstemitdefineEmits{change:[state:string]submit:[username:string,password:string]update:[id:number,data:object,timestamp:number]}()/script三、类型声明文件 .d.ts3.1 什么是类型声明文件在 TS 中以.d.ts为后缀的文件就是类型声明文件主要作用是为 JS 模块提供类型信息支持从而获得类型提示。比如 axios 本身是 JS 编写的但我们在写axios.时依然有代码提示这是因为 axios 的安装包中包含了index.d.ts类型声明文件。.d.ts文件会在你使用 JS 模块时被 TS 自动加载从而提供类型提示。如果库本身是使用 TS 编写的在打包的时候经过配置自动生成对应的.d.ts文件。3.2 使用 DefinitelyTyped 提供类型声明文件场景有些库本身并不是采用 TS 编写的无法直接生成配套的.d.ts文件如果也想获得类型提示就需要DefinitelyTyped提供类型声明文件。例如使用 jQueryimportjqueryfromjquery// ❌ 报错无法找到模块jquery的声明文件DefinitelyTyped是一个 TS 类型定义的仓库专门为 JS 编写的库提供类型声明types/库名。比如为 jQuery 提供类型提示可以安装types/jquerynpminstalltypes/jqueryimportjqueryfromjquery// ✅ 现在有类型提示了补充如何确定某个库是否受 DefinitelyTyped 支持呢推荐以下两种查询方式1.官方搜索工具访问 TypeScript Type Search输入库名即可快速查看是否存在对应的types包及其版本信息。2. npm 命令行查询在终端执行npm search types/库名若返回有效结果则说明该库已有社区维护的类型声明。3.3 TS 内置类型声明文件TS 为 JS 运行时可用的所有标准化内置 API 都提供了声明文件。这些文件既不需要编译生成也不需要三方提供。比如lib.es5.d.ts以及lib.dom.d.ts都是内置的类型声明文件为原生 JS 和浏览器 API 提供类型提示。鼠标放到every按住ctrl键就可以看到如下图内置ts文件的位置3.4 自定义类型声明文件.d.ts文件在项目中可以进行自定义创建通常有两种作用场景一TS 类型复用重要在项目中多个组件可能需要使用同一个类型定义比如User接口。如果每个组件都重复定义一遍不仅冗余维护起来也很麻烦。通过.d.ts文件可以把类型定义抽离出来供多个组件复用。在src/types/index.d.ts中定义类型exportinterfaceUser{id:stringname:stringage:number}在组件中直接导入使用scriptsetuplangts//注意实际导入时需根据文件位置调整路径示例中类型文件位于 src/types/index.d.tsimporttype{User}from/types/index;constuserInfo:User{id:1,name:张三,age:18};// ✅ 类型校验通过有完整的智能提示constuserInfo2:User{};//❌ 报错类型“{}”缺少类型“User”中的以下属性: id, name, age/script为了区分普通模块强烈推荐加上type关键词。场景二给 JS 文件提供类型了解通过declare关键词可以为 JS 文件中的变量声明对应类型这样 JS 导出的模块在使用的时候也会获得类型提示 .d.ts 文件需要和对应的 .js 文件保持同名仅后缀不同TS 才会自动关联类型声明。例如在一个文件夹内创建3个文件index.d.tsindex.js和main.vueindex.d.tstypeMathType(a:number,b:number)number;declareconstadd:MathType;declareconstsub:MathType;export{add,sub};index.jsexportconstadd(a,b){returnab;};exportconstsub(a,b){returna-b;};main.vueimport{add,sub}from./index.js;constn1add(1,2);// ✅ 正常constn2sub(3);// ❌ 报错应有 2 个参数但获得 1 个3.5 .ts 文件和 .d.ts 文件的区别TS 中有两种文件类型文件类型特点用途.ts文件既可以包含类型信息也可以写逻辑代码可以被编译为 JS 文件编写程序代码.d.ts文件只能包含类型信息不可以写逻辑代码不会被编译为 JS 文件仅做类型校验检查为 JS 提供类型声明小结知识点示例说明defineProps泛型definePropsProps()声明 props 类型withDefaultswithDefaults(definePropsProps(), {...})带默认值的 propsdefineEmits泛型defineEmitsEmits()声明事件类型.d.ts共享类型export interface User {}跨文件共享类型DefinitelyTypedtypes/jquery为 JS 库提供类型声明内置类型声明lib.es5.d.ts、lib.dom.d.ts原生 JS 和浏览器 API系列回顾为什么学 TypeScript—— 优势、场景与环境搭建TypeScript 核心语法入门 —— 类型注解与类型组合TypeScript 核心语法进阶 —— 函数与对象类型TypeScript 核心语法进阶 —— 字面量类型与类型推论TypeScript 高级特性 —— 类型断言与泛型TypeScript 核心语法应用 —— Vue 3 中的使用上TypeScript 核心语法应用 —— Vue 3 中的使用下到这里整个 TS 系列就全部结束了。从为什么要学 TS到基础语法、高级特性再到 Vue 3 中的具体写法希望能帮你从“会写 TypeScript”走到“能在项目里用好 TypeScript”。欢迎持续关注 参考资料Vue 3 官方文档 —— TypeScript 与组合式 APITypeScript 官方文档 —— 类型声明文件
返回列表