Vue3核心Typescript类解析
与使用JavaScript不同的是,用Typescript写Vue程序要需要了解Vue的相关类型。Vue核心的类型,大部分写在@vue/runtime-core包中。 Component 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 && CreateAppFunction 在V3中,一个页面的启动通常是从createApp开始的,它的类型声明是这样的: export type CreateAppFunction<HostElement> = ( rootComponent: Component, rootProps?: Data | null ) => App<HostElement> 它接受一个Component和属性作为参数,返回一个App。 App App实例是一个Vue的顶层对象,通过它可以设置共享属性、设置插件、注册组件、设置编译选项、设置错误处理函数等。 https://v3.cn.vuejs.org/api/application-api.html 通过mount方法可以将根组件挂载到文档中,并返回一个ComponentPublicInstance对象。 ComponentPublicInstance ComponentPublicInstance是组件实例,包含$el,'$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。