vue2患者看病,vue3搭配TypeScript使用入门

141 阅读4分钟
本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

在使用typescript编写vue3时,我们是有一些配置和基本的和vue3有关的基础知识或者说和纯的typescript不同的地方,这些都在vue3的指南文档中进行了详细的说明,我们这里做个记录

volar

这个和vue2的区别是很明显的,vue2中是推荐的Vetur,现在vue3官方推荐的是Volar,那首先就是这两个扩展插件冲突的问题,那就是我们正常的开启vue3项目的时候要确保Vetur被禁用状态,TypeScript Vue Plugin (Volar) 就是我们上面提到的问题,支持引入.vue文件的,不然会报错

volar的 takeover模式

因为volar为了使vue单文件和TypeScript在一个文件中可以正常工作,创建了一个针对vue的TypeScript语言服务实例,但是同时,vscode对普通的.ts文件有内置的服务实例,这样的话,就是在一个项目中,是运行了两个语言服务实例的,这在普通的项目中可能并不会带来太大影响,但是当项目越来越大,性能消耗也就越来越大,两个实例就会带来影响,理想状态下,肯定是保持一个是最合适的,这个就是volar提供的功能了,volar提供了一个特别的模式,专门可以接管的功能,就是takeover的中文意思,在开启了这个模式后,volar能够用一个实例,同时对 .vue.ts的文件进行服务,开启takeover模式的步骤如下(windows系统):

  • Ctrl + Shift + P 唤起命令界面
  • 在命令行输入: built 之后选择选项: Extensions: Show Built-in Extensions
  • 选择后会自动跳转到扩展中,并自带前缀 @builtin 接着继续输入 typescript
  • 跳出来的选项中点击第一个选项的设置按钮(右下角的齿轮)点击后选择: Disable(Workspace)
  • 之后重新加载就可以了,之后打开vue或者ts文件就会自动启用takeover模式

image.png

配置tsconfig.json

手动配置的话有如下几个注意点:

  • compilerOptions.isolatedModules 设置为true
  • 如果使用了选项式,这里不建议使用选项式,还是用组合式吧,我就不写了
  • 如果我们使用了路径别名,那我们需要在tsconfig中再配置一遍,如下图所示,不然的话使用不报错,但是编辑器中会提示别名找不到

image.png

image.png

接下来我们记录下文档中对在setup中使用TS的注意事项:

为ref()标注类型

ref会根据初始化的值推到其类型:

// 这里就会自动推到year的类型是number,赋值给year其他类型就会报错
const year = ref(2023)

这时候如果我们想给ref指定更为复杂的类型,可以通过**Ref**这个类型

import { ref } from 'vue'
import type { Ref } from 'vue'

const year: Ref<string | number> = ref('2023')
// 除了上面这种我们还可以使用泛型

const year = ref<string | number>('2023')

如果使用了泛型,但是没有给默认或者初始化的值,那么类型推导出的是 泛型 | undefined

为reactive 标注类型

隐式的类型推导和ref是一模一样的,我们主要来着重说一下显式标注一个reactive的变量类型,需要使用接口

import { reactive } from 'vue'

interface Book {
    title: string
    year?: number
}

const book: Book  = reactive({ title: 'vue3' })

为 computed() 标注类型

一样的,自动从计算函数的返回值上推导出类型,显式标注也是通过泛型:

const dou = computed<number>(()=> {
    // 若返回值不是number类型会报错
})

为事件处理函数标注类型

还是和上面的一样,如果我们没有标注的话,参数是隐式的类型的,不过不是推导了,这里是默认标注的都是any类型,这会在tsconfig.json中如果设置了strict: truenoImplicitAny: true,那么就会抛出一个TS错误,因此建议是显式的为事件处理函数的参数标注类型,此外,可能还需要显式的转换参数上的属性

function handleChange(event: Event) {
  console.log((event.target as HTMLInputElement).value)
}

为provide、 inject标注类型

vue中提供了一个InjectionKey接口,继承自一个Symbol的泛型类型,可以用来在提供者和消费者之间同步注入值的类型

import { provide, inject } from 'vue'
import type { InjectionKey } from 'vue'

const key = Symbol() as InjectionKey<string>

provide(key, 'foo')

const foo = Inject(key) // foo的类型: string | undefined