Vue3 中使用 TypeScript
-
像 TypeScript 这样的类型系统可以在编译时通过静态分析检测出很多常见错误。这减少了生产环境中的运行时错误,也让我们在重构大型项目的时候更有信心。通过 IDE 中基于类型的自动补全,TypeScript 还改善了开发体验和效率。
-
Vue 本身就是用 TypeScript 编写的,并对 TypeScript 提供了头等的支持。所有的 Vue 官方库都提供了类型声明文件,开箱即用。
一、准备工作
1.使用 create-vue 创建项目
npm init vue@3
2.在 Vite 中使用 TypeScript
-
Vite 天然支持引入 .ts 文件。
-
Vite 仅执行 .ts 文件的转译工作,并不执行任何类型检查。
-
并假设类型检查已经被你的 IDE 或构建过程接管了。
-
你可以在构建脚本中运行 tsc --noEmit。
-
或者安装 vue-tsc 然后运行 vue-tsc --noEmit 来对你的 *.vue 文件做类型检查。
-
Vite 使用 esbuild 将 TypeScript 转译到 JavaScript,约是 tsc 速度的 20~30 倍,同时 HMR 更新反映到浏览器的时间小于 50ms。
3.Ts 使用说明
defineComponent()
从 vue 导出的定义组件的新方法- 该方法定义一个能加 TS 的组件
import { defineComponent } from 'vue'
export default defineComponent({
props: {
name: String,
msg: {
type: String,
required: true
}
},
data() {
return {
count: 1
}
},
mounted() {
this.name
this.msg
this.count
const n: string | undefined = this.name
}
})
二、 TS 与组合式 API
1.为组件的 prop 标注类型
-
在组合式 API 中 ,
<script setup>
接收 props 时需要用到defineProps()
方法
const props = defineProps({})
-
defineProps() 里面的参数用法和 之前的 props 的方法是相同的
-
基于类型的声明
- 使用泛型定义 defineProps,在<>里级可以写 ts 代码了,不需要像传统的 js 那样写
const props = defineProps<{ foo: string; var: number; }>();
-
如果这个 props 使用很多,那可可以定义一个,接口来规定 defineProps 的 leix
interface Props { foo: string, bar: number } const props = defineProps<Props>() //这时候 props 中数据类型就和 接口Props一样
- 当 props 的内容有不穿的情况下,定义数据类型
interface Props { foo: string, bar?: number // 这个问号就表示 bar 可能不传参 ,那么在props接收参数的时候就可以给个默认值 } const { foo, bar = 10 } = defineProps<Props>()
-
2.为组建的 emit 标注类型
- 在 组合式 API 中获取 emit 使用方法
defineEmits()
- 给 emit 标注数据类型
const emit = defineEmits<{
// 这个 (传参类型 e:事件名 参数:参数类型) 返回值的类型
(e:'change',id:number) : number
(e:'update',value:string) : void
}>()
3.为 ref() 标志类型
- 使用以前的方法创建 ref() 数据
// 创建的是啥类型,year就是啥类型
const year = ref(2022)
- 使用 vue 中的
Ref
方法设置类型
import type { Ref } from 'vue'
// 可以规定 year 的类型
const year:Ref<string|number> = ref('2022')
4.为 reactive() 标注类型
- 使用之前的方法之间创建 reactive 数据
- 同样,各个数据创建的时候会根据初始值自动设置数据类型
const list = reactive({id:100,name:"fell"})
- 同样,各个数据创建的时候会根据初始值自动设置数据类型
- 使用 接口 规定数据类型
interface List {
id: number,
name: string
}
// 这样的情况下,如果创建初始值的时候,没有遵循接口List 的数据类型就会出错
const list: List = reactive({id:100,name:'fell'})
5.为 computed() 标注类型
- computed 计算属性 数据类型,其返回值的数据类型决定他的数据类型
- 他是 ComputedRef 类型的数据
import type { CompotedRef } from "vue";
const count = ref(100)
const addOne = computer(()=> count.value + 1)
// 这里的 addOne 是 ComputedRef<number>型
// 使用的时候要注意数据类型
// 还可以规定 返回值的类型,通过 泛型
const minusOne = conputed<boolean>(()=>true)
6.为事件处理器标注类型
// <input type="text" @change="handleChange">
function handlerChange(event:Event){
// console.log(event.target.value);
console.log((event.target as HTMLButtonElement).value);
}
// <button @click="handleClick">aa</button>
function handleClick(event: Event) {
console.log((event.target as HTMLButtonElement).innerHTML)
}
7.为 provide/inject 标注类型
- 使用
InjectionKey()
方法来设置
import { InjectionKey } from "vue"
// 可以定义一个 Symbol() 数据作为 provide 的key
const key = Symbol() as InjectionKey<string>
provide(key,'100')
8.为模板 ref 标注类型
// <input type="text" ref="ipt">
const ipt = ref<HTMLInputElement | null>(null)