与使用JavaScript不同的是,用Typescript写Vue程序要需要了解Vue的相关类型。Vue核心的类型,大部分写在@vue/runtime-core包中。
Vue页面是由一个个组件组成的,组件在Vue中的类是Component
,继承了ComponentOptions
、FunctionalComponent
和ComponentPublicInstanceConstructor
。
其中,ComponentOptions
继承了ComponentOptionsBase
,就是是我们经常写的声明式的包含data
、methods
等属性的选项组件:
FunctionalComponent
是函数式组件,ComponentPublicInstanceConstructor
是实例构造器(构造函数)。
ComponentOptions
继承了ComponentCustomOptions
,这个接口在Vue源码中是空的,我们可以借助它了自定义Vue组件选项中的属性,比如源码中的例子:
declare module '@vue/runtime-core' {
interface ComponentCustomOptions {
beforeRouteUpdate?(
to: Route,
from: Route,
next: () => void
): void
}
}
我们在定义组件时使用的defineComponent
函数用于帮助我们进行组件选项的类型声明,它接受ComponentOptionsWithoutProps
,ComponentOptionsWithArrayProps
或ComponentOptionsWithObjectProps
作为选项参数。它们都继承了ComponentOptionsBase
,但具有不同的声明props的形式。这个函数也可以接受setup函数。
defineComponent
函数返回DefineComponent
类对象,它是ComponentOptionsBase
和ComponentPublicInstanceConstructor
的交集类对象:
type DefineComponent = ComponentPublicInstanceConstructor & ComponentOptionsBase &&
在V3中,一个页面的启动通常是从createApp
开始的,它的类型声明是这样的:
export type CreateAppFunction<HostElement> = (
rootComponent: Component,
rootProps?: Data | null
) => App<HostElement>
它接受一个Component
和属性作为参数,返回一个App
。
App
实例是一个Vue的顶层对象,通过它可以设置共享属性、设置插件、注册组件、设置编译选项、设置错误处理函数等。
通过mount
方法可以将根组件挂载到文档中,并返回一个ComponentPublicInstance
对象。
ComponentPublicInstance
是组件实例,包含$el
,'emit‘‘emit‘‘props等属性。Vue以
Component为模板,创建了
ComponentPublicInstance`。
它的类型定义为:
type ComponentPublicInstance<
P = {}, // props type extracted from props option
B = {}, // raw bindings returned from setup()
D = {}, // return from data()
C extends ComputedOptions = {},
M extends MethodOptions = {},
E extends EmitsOptions = {},
PublicProps = P,
Defaults = {},
MakeDefaultsOptional extends boolean = false,
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>
> = {
$: ComponentInternalInstance
$data: D
$props: MakeDefaultsOptional extends true
? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults>
: P & PublicProps
$attrs: Data
$refs: Data
$slots: Slots
$root: ComponentPublicInstance | null
$parent: ComponentPublicInstance | null
$emit: EmitFn<E>
$el: any
$options: Options & MergedComponentOptionsOverride
$forceUpdate: () => void
$nextTick: typeof nextTick
$watch(
source: string | Function,
cb: Function,
options?: WatchOptions
): WatchStopHandle
} & P &
ShallowUnwrapRef<B> &
UnwrapNestedRefs<D> &
ExtractComputedReturns<C> &
M &
ComponentCustomProperties
其中$options
就是我们在写组件时的ComponentOptionsBase
类对象(如果有的话,对于函数式组件则包含一个renderer
方法)和MergedComponentOptionsOverride(钩子函数)交集类。
P
、ShallowUnwrapRef
、UnwrapNestedRefs
、ExtractComputedReturns
、M
帮助我们可以用this[...]的方式读取组件实例的数据属性和方法。
ComponentCustomProperties
在源码中是一个空接口,我们可以通过它来自定义组件实例上的属性。示例:
import { Router } from 'vue-router'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$router: Router
}
}
$
属性是ComponentInternalInstance
类对象,表示组件的内部示例,包含了一些为高级应用提供的属性,包括VNode
。