Vue3学习笔记-07 TypeScript支持
Vue3对TypeScript的支持比Vue2更加强大,因为Vue3本身就是用TypeScript编写的
项目创建
可以使用Vue CLI来直接生成使用TypeScript的新项目
1 2 3 4 5 6 7 8
| npm install --global @vue/cli@next
vue create my-project-name
vue add typescript
|
组件的<srcipt>
的lang
属性应该设置为ts
定义组件
让TypeScript正确推断Vue组件选项中的类型,需要使用defineComponent
全局方法定义组件
1 2 3 4 5
| import { defineComponent } from 'vue'
export default defineComponent({ })
|
选项式API的类型推断
通过defineComponent
后,定义在data
中的数据回自动被推断类型
1 2 3 4 5 6 7 8 9 10
| const Component = defineComponent({ data() { return { count: 0 } }, mounted() { const result = this.count.split('') } })
|
这个时候,count
会被推断为数字类型,但是如果是一个复杂的类型或者结果,需要使用断言来对进行强制转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| interface Book { title: string author: string year: number }
const Component = defineComponent({ data() { return { book: { title: 'Vue 3 Guide', author: 'Vue Team', year: 2020 } as Book } } })
|
计算属性的类型
计算属性类型需要显式的声明计算属性的返回类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import { defineComponent } from 'vue'
const Component = defineComponent({ data() { return { message: 'Hello!' } }, computed: { greeting(): string { return this.message + '!' }
greetingUppercased: { get(): string { return this.greeting.toUpperCase(); }, set(newValue: string) { this.message = newValue.toUpperCase(); }, }, } })
|
Props的类型
Vue对定义了type
的Prop执行运行时验证,需要通过PropType
强制转换构造函数,将类型提供给TypeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { defineComponent, PropType } from 'vue'
interface Book { title: string author: string year: number }
const Component = defineComponent({ props: { name: String, success: { type: String }, callback: { type: Function as PropType<() => void> }, book: { type: Object as PropType<Book>, required: true } } })
|
涉及到Prop的validators
和default
进行类型推断时,要注意this
的类型,需要使用箭头函数,或者明确提供this
参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import { defineComponent, PropType } from 'vue'
interface Book { title: string year?: number }
const Component = defineComponent({ props: { bookA: { type: Object as PropType<Book>, default: () => ({ title: 'Arrow Function Expression' }), validator: (book: Book) => !!book.title }, bookB: { type: Object as PropType<Book>, default(this: void) { return { title: 'Function Expression' } }, validator(this: void, book: Book) { return !!book.title } } } })
|
Emit类型
Vue3的选项中新增了emits
选项,它的主要目的就是避免的Vue2.x中隐式的定义emit
事件的弊端,并且可以显示的指明Emit的载荷类型
不需要类型注解时,emits
接受一个数组,数组成员是字符串组成的事件名,需要类型注解时,接受的参数是这个Emit事件的校验函数,这样就可以校验每一个Emit的参数和返回值(与Prop的Validator类似)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const Component = defineComponent({ emits: { addBook(payload: { bookName: string }) { return payload.bookName.length > 0 } }, methods: { onSubmit() { this.$emit('addBook', { bookName: 123 }) this.$emit('non-declared-event') } } })
|
与组合式API一起使用
在setup()
函数中,不需要为props
参数传递类型,它会从组件的Prop选项中推断类型
ref
类型
Refs类型会根据初始值进行推断,如果Ref是一个复杂类型,可以通过传给ref
一个泛型类指定类型
1 2 3
| const year = ref<string | number>('2020')
year.value = 2020
|
reactive
类型
声明reactive
类型可以使用接口,作为泛型传给reative
,或者作为变量的类型也可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import { defineComponent, reactive } from 'vue'
interface Book { title: string year?: number }
export default defineComponent({ name: 'HelloWorld', setup() { const book = reactive<Book>({ title: 'Vue 3 Guide' }) const book: Book = reactive({ title: 'Vue 3 Guide' }) const book = reactive({ title: 'Vue 3 Guide' }) as Book } })
|