mirror of https://github.com/vuejs/core.git
types(defineComponent): support for GlobalComponents, typed Directives and respect `expose` on defineComponent (#3399)
close #3367
This commit is contained in:
parent
0e6e3c7eb0
commit
4cc9ca870c
|
@ -1,4 +1,4 @@
|
||||||
import { defineComponent } from 'vue'
|
import { type DefineComponent, type Directive, defineComponent } from 'vue'
|
||||||
import { expectType } from './utils'
|
import { expectType } from './utils'
|
||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
|
@ -6,6 +6,14 @@ declare module 'vue' {
|
||||||
test?(n: number): void
|
test?(n: number): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GlobalDirectives {
|
||||||
|
test: Directive
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GlobalComponents {
|
||||||
|
RouterView: DefineComponent<{}>
|
||||||
|
}
|
||||||
|
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
state?: 'stopped' | 'running'
|
state?: 'stopped' | 'running'
|
||||||
}
|
}
|
||||||
|
@ -46,6 +54,8 @@ export const Custom = defineComponent({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expectType<Directive>(Custom.directives!.test)
|
||||||
|
expectType<DefineComponent<{}>>(Custom.components!.RouterView)
|
||||||
expectType<JSX.Element>(<Custom baz={1} />)
|
expectType<JSX.Element>(<Custom baz={1} />)
|
||||||
expectType<JSX.Element>(<Custom custom={1} baz={1} />)
|
expectType<JSX.Element>(<Custom custom={1} baz={1} />)
|
||||||
expectType<JSX.Element>(<Custom bar="bar" baz={1} />)
|
expectType<JSX.Element>(<Custom bar="bar" baz={1} />)
|
||||||
|
|
|
@ -1501,18 +1501,108 @@ describe('should work when props type is incompatible with setup returned type '
|
||||||
|
|
||||||
describe('withKeys and withModifiers as pro', () => {
|
describe('withKeys and withModifiers as pro', () => {
|
||||||
const onKeydown = withKeys(e => {}, [''])
|
const onKeydown = withKeys(e => {}, [''])
|
||||||
|
// @ts-expect-error invalid modifiers
|
||||||
const onClick = withModifiers(e => {}, [''])
|
const onClick = withModifiers(e => {}, [''])
|
||||||
;<input onKeydown={onKeydown} onClick={onClick} />
|
;<input onKeydown={onKeydown} onClick={onClick} />
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #3367 expose components types
|
||||||
|
describe('expose component types', () => {
|
||||||
|
const child = defineComponent({
|
||||||
|
props: {
|
||||||
|
a: String,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const parent = defineComponent({
|
||||||
|
components: {
|
||||||
|
child,
|
||||||
|
child2: {
|
||||||
|
template: `<div></div>`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expectType<typeof child>(parent.components!.child)
|
||||||
|
expectType<Component>(parent.components!.child2)
|
||||||
|
|
||||||
|
// global components
|
||||||
|
expectType<Readonly<KeepAliveProps>>(
|
||||||
|
new parent.components!.KeepAlive().$props,
|
||||||
|
)
|
||||||
|
expectType<Readonly<KeepAliveProps>>(new child.components!.KeepAlive().$props)
|
||||||
|
|
||||||
|
// runtime-dom components
|
||||||
|
expectType<Readonly<TransitionProps>>(
|
||||||
|
new parent.components!.Transition().$props,
|
||||||
|
)
|
||||||
|
expectType<Readonly<TransitionProps>>(
|
||||||
|
new child.components!.Transition().$props,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('directive typing', () => {
|
||||||
|
const customDirective: Directive = {
|
||||||
|
created(_) {},
|
||||||
|
}
|
||||||
|
|
||||||
|
const comp = defineComponent({
|
||||||
|
props: {
|
||||||
|
a: String,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
customDirective,
|
||||||
|
localDirective: {
|
||||||
|
created(_, { arg }) {
|
||||||
|
expectType<string | undefined>(arg)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expectType<typeof customDirective>(comp.directives!.customDirective)
|
||||||
|
expectType<Directive>(comp.directives!.localDirective)
|
||||||
|
|
||||||
|
// global directive
|
||||||
|
expectType<typeof vShow>(comp.directives!.vShow)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('expose typing', () => {
|
||||||
|
const Comp = defineComponent({
|
||||||
|
expose: ['a', 'b'],
|
||||||
|
props: {
|
||||||
|
some: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { a: 1, b: '2', c: 1 }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expectType<Array<'a' | 'b'>>(Comp.expose!)
|
||||||
|
|
||||||
|
const vm = new Comp()
|
||||||
|
// internal should still be exposed
|
||||||
|
vm.$props
|
||||||
|
|
||||||
|
expectType<number>(vm.a)
|
||||||
|
expectType<string>(vm.b)
|
||||||
|
|
||||||
|
// @ts-expect-error shouldn't be exposed
|
||||||
|
vm.c
|
||||||
|
})
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
AllowedComponentProps,
|
AllowedComponentProps,
|
||||||
ComponentCustomProps,
|
ComponentCustomProps,
|
||||||
ComponentOptionsMixin,
|
ComponentOptionsMixin,
|
||||||
DefineComponent,
|
DefineComponent,
|
||||||
|
Directive,
|
||||||
EmitsOptions,
|
EmitsOptions,
|
||||||
ExtractPropTypes,
|
ExtractPropTypes,
|
||||||
|
KeepAliveProps,
|
||||||
|
TransitionProps,
|
||||||
VNodeProps,
|
VNodeProps,
|
||||||
|
vShow,
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
|
|
||||||
// code generated by tsc / vue-tsc, make sure this continues to work
|
// code generated by tsc / vue-tsc, make sure this continues to work
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { type Directive, type ObjectDirective, vModelText } from 'vue'
|
||||||
|
import { describe, expectType } from './utils'
|
||||||
|
|
||||||
|
type ExtractBinding<T> = T extends (
|
||||||
|
el: any,
|
||||||
|
binding: infer B,
|
||||||
|
vnode: any,
|
||||||
|
prev: any,
|
||||||
|
) => any
|
||||||
|
? B
|
||||||
|
: never
|
||||||
|
|
||||||
|
declare function testDirective<
|
||||||
|
Value,
|
||||||
|
Modifiers extends string = string,
|
||||||
|
Arg extends string = string,
|
||||||
|
>(): ExtractBinding<Directive<any, Value, Modifiers, Arg>>
|
||||||
|
|
||||||
|
describe('vmodel', () => {
|
||||||
|
expectType<ObjectDirective<any, any, 'trim' | 'number' | 'lazy', string>>(
|
||||||
|
vModelText,
|
||||||
|
)
|
||||||
|
// @ts-expect-error
|
||||||
|
expectType<ObjectDirective<any, any, 'not-valid', string>>(vModelText)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('custom', () => {
|
||||||
|
expectType<{
|
||||||
|
value: number
|
||||||
|
oldValue: number | null
|
||||||
|
arg?: 'Arg'
|
||||||
|
modifiers: Record<'a' | 'b', boolean>
|
||||||
|
}>(testDirective<number, 'a' | 'b', 'Arg'>())
|
||||||
|
|
||||||
|
expectType<{
|
||||||
|
value: number
|
||||||
|
oldValue: number | null
|
||||||
|
arg?: 'Arg'
|
||||||
|
modifiers: Record<'a' | 'b', boolean>
|
||||||
|
// @ts-expect-error
|
||||||
|
}>(testDirective<number, 'a', 'Arg'>())
|
||||||
|
|
||||||
|
expectType<{
|
||||||
|
value: number
|
||||||
|
oldValue: number | null
|
||||||
|
arg?: 'Arg'
|
||||||
|
modifiers: Record<'a' | 'b', boolean>
|
||||||
|
// @ts-expect-error
|
||||||
|
}>(testDirective<number, 'a' | 'b', 'Argx'>())
|
||||||
|
|
||||||
|
expectType<{
|
||||||
|
value: number
|
||||||
|
oldValue: number | null
|
||||||
|
arg?: 'Arg'
|
||||||
|
modifiers: Record<'a' | 'b', boolean>
|
||||||
|
// @ts-expect-error
|
||||||
|
}>(testDirective<string, 'a' | 'b', 'Arg'>())
|
||||||
|
})
|
|
@ -6,13 +6,17 @@ import type {
|
||||||
ComponentOptionsWithArrayProps,
|
ComponentOptionsWithArrayProps,
|
||||||
ComponentOptionsWithObjectProps,
|
ComponentOptionsWithObjectProps,
|
||||||
ComponentOptionsWithoutProps,
|
ComponentOptionsWithoutProps,
|
||||||
|
ComponentProvideOptions,
|
||||||
ComputedOptions,
|
ComputedOptions,
|
||||||
MethodOptions,
|
MethodOptions,
|
||||||
RenderFunction,
|
RenderFunction,
|
||||||
} from './componentOptions'
|
} from './componentOptions'
|
||||||
import type {
|
import type {
|
||||||
AllowedComponentProps,
|
AllowedComponentProps,
|
||||||
|
Component,
|
||||||
ComponentCustomProps,
|
ComponentCustomProps,
|
||||||
|
GlobalComponents,
|
||||||
|
GlobalDirectives,
|
||||||
SetupContext,
|
SetupContext,
|
||||||
} from './component'
|
} from './component'
|
||||||
import type {
|
import type {
|
||||||
|
@ -29,6 +33,7 @@ import type {
|
||||||
CreateComponentPublicInstance,
|
CreateComponentPublicInstance,
|
||||||
} from './componentPublicInstance'
|
} from './componentPublicInstance'
|
||||||
import type { SlotsType } from './componentSlots'
|
import type { SlotsType } from './componentSlots'
|
||||||
|
import type { Directive } from './directives'
|
||||||
|
|
||||||
export type PublicProps = VNodeProps &
|
export type PublicProps = VNodeProps &
|
||||||
AllowedComponentProps &
|
AllowedComponentProps &
|
||||||
|
@ -55,6 +60,10 @@ export type DefineComponent<
|
||||||
Props = ResolveProps<PropsOrPropOptions, E>,
|
Props = ResolveProps<PropsOrPropOptions, E>,
|
||||||
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>,
|
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>,
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
> = ComponentPublicInstanceConstructor<
|
> = ComponentPublicInstanceConstructor<
|
||||||
CreateComponentPublicInstance<
|
CreateComponentPublicInstance<
|
||||||
Props,
|
Props,
|
||||||
|
@ -69,7 +78,10 @@ export type DefineComponent<
|
||||||
Defaults,
|
Defaults,
|
||||||
true,
|
true,
|
||||||
{},
|
{},
|
||||||
S
|
S,
|
||||||
|
LC & GlobalComponents,
|
||||||
|
Directives & GlobalDirectives,
|
||||||
|
Exposed
|
||||||
>
|
>
|
||||||
> &
|
> &
|
||||||
ComponentOptionsBase<
|
ComponentOptionsBase<
|
||||||
|
@ -85,7 +97,11 @@ export type DefineComponent<
|
||||||
Defaults,
|
Defaults,
|
||||||
{},
|
{},
|
||||||
string,
|
string,
|
||||||
S
|
S,
|
||||||
|
LC & GlobalComponents,
|
||||||
|
Directives & GlobalDirectives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
> &
|
> &
|
||||||
PP
|
PP
|
||||||
|
|
||||||
|
@ -166,9 +182,13 @@ export function defineComponent<
|
||||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||||
E extends EmitsOptions = {},
|
E extends EmitsOptions = {},
|
||||||
EE extends string = string,
|
EE extends string = string,
|
||||||
S extends SlotsType = {},
|
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
>(
|
>(
|
||||||
options: ComponentOptionsWithoutProps<
|
options: ComponentOptionsWithoutProps<
|
||||||
Props,
|
Props,
|
||||||
|
@ -182,7 +202,11 @@ export function defineComponent<
|
||||||
EE,
|
EE,
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>,
|
>,
|
||||||
): DefineComponent<
|
): DefineComponent<
|
||||||
Props,
|
Props,
|
||||||
|
@ -197,7 +221,11 @@ export function defineComponent<
|
||||||
PublicProps,
|
PublicProps,
|
||||||
ResolveProps<Props, E>,
|
ResolveProps<Props, E>,
|
||||||
ExtractDefaultPropTypes<Props>,
|
ExtractDefaultPropTypes<Props>,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>
|
>
|
||||||
|
|
||||||
// overload 3: object format with array props declaration
|
// overload 3: object format with array props declaration
|
||||||
|
@ -216,6 +244,10 @@ export function defineComponent<
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
Props = Readonly<{ [key in PropNames]?: any }>,
|
Props = Readonly<{ [key in PropNames]?: any }>,
|
||||||
>(
|
>(
|
||||||
options: ComponentOptionsWithArrayProps<
|
options: ComponentOptionsWithArrayProps<
|
||||||
|
@ -230,7 +262,11 @@ export function defineComponent<
|
||||||
EE,
|
EE,
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>,
|
>,
|
||||||
): DefineComponent<
|
): DefineComponent<
|
||||||
Props,
|
Props,
|
||||||
|
@ -245,7 +281,11 @@ export function defineComponent<
|
||||||
PublicProps,
|
PublicProps,
|
||||||
ResolveProps<Props, E>,
|
ResolveProps<Props, E>,
|
||||||
ExtractDefaultPropTypes<Props>,
|
ExtractDefaultPropTypes<Props>,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>
|
>
|
||||||
|
|
||||||
// overload 4: object format with object props declaration
|
// overload 4: object format with object props declaration
|
||||||
|
@ -262,9 +302,13 @@ export function defineComponent<
|
||||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||||
E extends EmitsOptions = {},
|
E extends EmitsOptions = {},
|
||||||
EE extends string = string,
|
EE extends string = string,
|
||||||
S extends SlotsType = {},
|
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
>(
|
>(
|
||||||
options: ComponentOptionsWithObjectProps<
|
options: ComponentOptionsWithObjectProps<
|
||||||
PropsOptions,
|
PropsOptions,
|
||||||
|
@ -278,7 +322,11 @@ export function defineComponent<
|
||||||
EE,
|
EE,
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>,
|
>,
|
||||||
): DefineComponent<
|
): DefineComponent<
|
||||||
PropsOptions,
|
PropsOptions,
|
||||||
|
@ -293,7 +341,11 @@ export function defineComponent<
|
||||||
PublicProps,
|
PublicProps,
|
||||||
ResolveProps<PropsOptions, E>,
|
ResolveProps<PropsOptions, E>,
|
||||||
ExtractDefaultPropTypes<PropsOptions>,
|
ExtractDefaultPropTypes<PropsOptions>,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>
|
>
|
||||||
|
|
||||||
// implementation, close to no-op
|
// implementation, close to no-op
|
||||||
|
|
|
@ -86,6 +86,13 @@ import {
|
||||||
import type { SchedulerJob } from './scheduler'
|
import type { SchedulerJob } from './scheduler'
|
||||||
import type { LifecycleHooks } from './enums'
|
import type { LifecycleHooks } from './enums'
|
||||||
|
|
||||||
|
// Augment GlobalComponents
|
||||||
|
import type { TeleportProps } from './components/Teleport'
|
||||||
|
import type { SuspenseProps } from './components/Suspense'
|
||||||
|
import type { KeepAliveProps } from './components/KeepAlive'
|
||||||
|
import type { BaseTransitionProps } from './components/BaseTransition'
|
||||||
|
import type { DefineComponent } from './apiDefineComponent'
|
||||||
|
|
||||||
export type Data = Record<string, unknown>
|
export type Data = Record<string, unknown>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,6 +133,45 @@ export type ComponentInstance<T> = T extends { new (): ComponentPublicInstance }
|
||||||
*/
|
*/
|
||||||
export interface ComponentCustomProps {}
|
export interface ComponentCustomProps {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For globally defined Directives
|
||||||
|
* Here is an example of adding a directive `VTooltip` as global directive:
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import VTooltip from 'v-tooltip'
|
||||||
|
*
|
||||||
|
* declare module '@vue/runtime-core' {
|
||||||
|
* interface GlobalDirectives {
|
||||||
|
* VTooltip
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export interface GlobalDirectives extends Record<string, Directive> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For globally defined Components
|
||||||
|
* Here is an example of adding a component `RouterView` as global component:
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* import { RouterView } from 'vue-router'
|
||||||
|
*
|
||||||
|
* declare module '@vue/runtime-core' {
|
||||||
|
* interface GlobalComponents {
|
||||||
|
* RouterView
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export interface GlobalComponents extends Record<string, Component> {
|
||||||
|
Teleport: DefineComponent<TeleportProps>
|
||||||
|
Suspense: DefineComponent<SuspenseProps>
|
||||||
|
KeepAlive: DefineComponent<KeepAliveProps>
|
||||||
|
BaseTransition: DefineComponent<BaseTransitionProps>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default allowed non-declared props on component in TSX
|
* Default allowed non-declared props on component in TSX
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -112,7 +112,11 @@ export interface ComponentOptionsBase<
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
> extends LegacyOptions<Props, D, C, M, Mixin, Extends, I, II>,
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
|
> extends LegacyOptions<Props, D, C, M, Mixin, Extends, I, II, Provide>,
|
||||||
ComponentInternalOptions,
|
ComponentInternalOptions,
|
||||||
ComponentCustomOptions {
|
ComponentCustomOptions {
|
||||||
setup?: (
|
setup?: (
|
||||||
|
@ -136,13 +140,16 @@ export interface ComponentOptionsBase<
|
||||||
// Luckily `render()` doesn't need any arguments nor does it care about return
|
// Luckily `render()` doesn't need any arguments nor does it care about return
|
||||||
// type.
|
// type.
|
||||||
render?: Function
|
render?: Function
|
||||||
components?: Record<string, Component>
|
// NOTE: extending both LC and Record<string, Component> allows objects to be forced
|
||||||
directives?: Record<string, Directive>
|
// to be of type Component, while still inferring LC generic
|
||||||
|
components?: LC & Record<string, Component>
|
||||||
|
// NOTE: extending both Directives and Record<string, Directive> allows objects to be forced
|
||||||
|
// to be of type Directive, while still inferring Directives generic
|
||||||
|
directives?: Directives & Record<string, Directive>
|
||||||
inheritAttrs?: boolean
|
inheritAttrs?: boolean
|
||||||
emits?: (E | EE[]) & ThisType<void>
|
emits?: (E | EE[]) & ThisType<void>
|
||||||
slots?: S
|
slots?: S
|
||||||
// TODO infer public instance type based on exposed keys
|
expose?: Exposed[]
|
||||||
expose?: string[]
|
|
||||||
serverPrefetch?(): void | Promise<any>
|
serverPrefetch?(): void | Promise<any>
|
||||||
|
|
||||||
// Runtime compiler only -----------------------------------------------------
|
// Runtime compiler only -----------------------------------------------------
|
||||||
|
@ -224,6 +231,10 @@ export type ComponentOptionsWithoutProps<
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
PE = Props & EmitsToProps<E>,
|
PE = Props & EmitsToProps<E>,
|
||||||
> = ComponentOptionsBase<
|
> = ComponentOptionsBase<
|
||||||
PE,
|
PE,
|
||||||
|
@ -238,7 +249,11 @@ export type ComponentOptionsWithoutProps<
|
||||||
{},
|
{},
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
> & {
|
> & {
|
||||||
props?: undefined
|
props?: undefined
|
||||||
} & ThisType<
|
} & ThisType<
|
||||||
|
@ -255,7 +270,10 @@ export type ComponentOptionsWithoutProps<
|
||||||
{},
|
{},
|
||||||
false,
|
false,
|
||||||
I,
|
I,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -272,6 +290,10 @@ export type ComponentOptionsWithArrayProps<
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
Props = Prettify<Readonly<{ [key in PropNames]?: any } & EmitsToProps<E>>>,
|
Props = Prettify<Readonly<{ [key in PropNames]?: any } & EmitsToProps<E>>>,
|
||||||
> = ComponentOptionsBase<
|
> = ComponentOptionsBase<
|
||||||
Props,
|
Props,
|
||||||
|
@ -286,7 +308,11 @@ export type ComponentOptionsWithArrayProps<
|
||||||
{},
|
{},
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
> & {
|
> & {
|
||||||
props: PropNames[]
|
props: PropNames[]
|
||||||
} & ThisType<
|
} & ThisType<
|
||||||
|
@ -303,7 +329,10 @@ export type ComponentOptionsWithArrayProps<
|
||||||
{},
|
{},
|
||||||
false,
|
false,
|
||||||
I,
|
I,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -320,6 +349,10 @@ export type ComponentOptionsWithObjectProps<
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
II extends string = string,
|
II extends string = string,
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
Props = Prettify<Readonly<ExtractPropTypes<PropsOptions> & EmitsToProps<E>>>,
|
Props = Prettify<Readonly<ExtractPropTypes<PropsOptions> & EmitsToProps<E>>>,
|
||||||
Defaults = ExtractDefaultPropTypes<PropsOptions>,
|
Defaults = ExtractDefaultPropTypes<PropsOptions>,
|
||||||
> = ComponentOptionsBase<
|
> = ComponentOptionsBase<
|
||||||
|
@ -335,7 +368,11 @@ export type ComponentOptionsWithObjectProps<
|
||||||
Defaults,
|
Defaults,
|
||||||
I,
|
I,
|
||||||
II,
|
II,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
> & {
|
> & {
|
||||||
props: PropsOptions & ThisType<void>
|
props: PropsOptions & ThisType<void>
|
||||||
} & ThisType<
|
} & ThisType<
|
||||||
|
@ -352,7 +389,9 @@ export type ComponentOptionsWithObjectProps<
|
||||||
Defaults,
|
Defaults,
|
||||||
false,
|
false,
|
||||||
I,
|
I,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -365,7 +404,15 @@ export type ComponentOptions<
|
||||||
Mixin extends ComponentOptionsMixin = any,
|
Mixin extends ComponentOptionsMixin = any,
|
||||||
Extends extends ComponentOptionsMixin = any,
|
Extends extends ComponentOptionsMixin = any,
|
||||||
E extends EmitsOptions = any,
|
E extends EmitsOptions = any,
|
||||||
S extends SlotsType = any,
|
EE extends string = string,
|
||||||
|
Defaults = {},
|
||||||
|
I extends ComponentInjectOptions = {},
|
||||||
|
II extends string = string,
|
||||||
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
> = ComponentOptionsBase<
|
> = ComponentOptionsBase<
|
||||||
Props,
|
Props,
|
||||||
RawBindings,
|
RawBindings,
|
||||||
|
@ -375,8 +422,15 @@ export type ComponentOptions<
|
||||||
Mixin,
|
Mixin,
|
||||||
Extends,
|
Extends,
|
||||||
E,
|
E,
|
||||||
string,
|
EE,
|
||||||
S
|
Defaults,
|
||||||
|
I,
|
||||||
|
II,
|
||||||
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
> &
|
> &
|
||||||
ThisType<
|
ThisType<
|
||||||
CreateComponentPublicInstance<
|
CreateComponentPublicInstance<
|
||||||
|
@ -388,7 +442,13 @@ export type ComponentOptions<
|
||||||
Mixin,
|
Mixin,
|
||||||
Extends,
|
Extends,
|
||||||
E,
|
E,
|
||||||
Readonly<Props>
|
Readonly<Props>,
|
||||||
|
Defaults,
|
||||||
|
false,
|
||||||
|
I,
|
||||||
|
S,
|
||||||
|
LC,
|
||||||
|
Directives
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -403,6 +463,12 @@ export type ComponentOptionsMixin = ComponentOptionsBase<
|
||||||
any,
|
any,
|
||||||
any,
|
any,
|
||||||
any,
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
any
|
any
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -464,6 +530,7 @@ interface LegacyOptions<
|
||||||
Extends extends ComponentOptionsMixin,
|
Extends extends ComponentOptionsMixin,
|
||||||
I extends ComponentInjectOptions,
|
I extends ComponentInjectOptions,
|
||||||
II extends string,
|
II extends string,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
> {
|
> {
|
||||||
compatConfig?: CompatConfig
|
compatConfig?: CompatConfig
|
||||||
|
|
||||||
|
@ -497,7 +564,7 @@ interface LegacyOptions<
|
||||||
computed?: C
|
computed?: C
|
||||||
methods?: M
|
methods?: M
|
||||||
watch?: ComponentWatchOptions
|
watch?: ComponentWatchOptions
|
||||||
provide?: ComponentProvideOptions
|
provide?: Provide
|
||||||
inject?: I | II[]
|
inject?: I | II[]
|
||||||
|
|
||||||
// assets
|
// assets
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
type Component,
|
||||||
type ComponentInternalInstance,
|
type ComponentInternalInstance,
|
||||||
type Data,
|
type Data,
|
||||||
getExposeProxy,
|
getExposeProxy,
|
||||||
|
@ -35,6 +36,7 @@ import {
|
||||||
type ComponentInjectOptions,
|
type ComponentInjectOptions,
|
||||||
type ComponentOptionsBase,
|
type ComponentOptionsBase,
|
||||||
type ComponentOptionsMixin,
|
type ComponentOptionsMixin,
|
||||||
|
type ComponentProvideOptions,
|
||||||
type ComputedOptions,
|
type ComputedOptions,
|
||||||
type ExtractComputedReturns,
|
type ExtractComputedReturns,
|
||||||
type InjectToObject,
|
type InjectToObject,
|
||||||
|
@ -51,6 +53,7 @@ import { markAttrsAccessed } from './componentRenderUtils'
|
||||||
import { currentRenderingInstance } from './componentRenderContext'
|
import { currentRenderingInstance } from './componentRenderContext'
|
||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
import { installCompatInstanceProperties } from './compat/instance'
|
import { installCompatInstanceProperties } from './compat/instance'
|
||||||
|
import type { Directive } from './directives'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom properties added to component instances in any way and can be accessed through `this`
|
* Custom properties added to component instances in any way and can be accessed through `this`
|
||||||
|
@ -99,6 +102,10 @@ type MixinToOptionTypes<T> =
|
||||||
infer Defaults,
|
infer Defaults,
|
||||||
any,
|
any,
|
||||||
any,
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
|
any,
|
||||||
any
|
any
|
||||||
>
|
>
|
||||||
? OptionTypesType<P & {}, B & {}, D & {}, C & {}, M & {}, Defaults & {}> &
|
? OptionTypesType<P & {}, B & {}, D & {}, C & {}, M & {}, Defaults & {}> &
|
||||||
|
@ -157,6 +164,9 @@ export type CreateComponentPublicInstance<
|
||||||
MakeDefaultsOptional extends boolean = false,
|
MakeDefaultsOptional extends boolean = false,
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
LC extends Record<string, Component> = {},
|
||||||
|
Directives extends Record<string, Directive> = {},
|
||||||
|
Exposed extends string = string,
|
||||||
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>,
|
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>,
|
||||||
PublicP = UnwrapMixinsType<PublicMixin, 'P'> & EnsureNonVoid<P>,
|
PublicP = UnwrapMixinsType<PublicMixin, 'P'> & EnsureNonVoid<P>,
|
||||||
PublicB = UnwrapMixinsType<PublicMixin, 'B'> & EnsureNonVoid<B>,
|
PublicB = UnwrapMixinsType<PublicMixin, 'B'> & EnsureNonVoid<B>,
|
||||||
|
@ -167,6 +177,7 @@ export type CreateComponentPublicInstance<
|
||||||
EnsureNonVoid<M>,
|
EnsureNonVoid<M>,
|
||||||
PublicDefaults = UnwrapMixinsType<PublicMixin, 'Defaults'> &
|
PublicDefaults = UnwrapMixinsType<PublicMixin, 'Defaults'> &
|
||||||
EnsureNonVoid<Defaults>,
|
EnsureNonVoid<Defaults>,
|
||||||
|
Provide extends ComponentProvideOptions = ComponentProvideOptions,
|
||||||
> = ComponentPublicInstance<
|
> = ComponentPublicInstance<
|
||||||
PublicP,
|
PublicP,
|
||||||
PublicB,
|
PublicB,
|
||||||
|
@ -190,11 +201,22 @@ export type CreateComponentPublicInstance<
|
||||||
Defaults,
|
Defaults,
|
||||||
{},
|
{},
|
||||||
string,
|
string,
|
||||||
S
|
S,
|
||||||
|
LC,
|
||||||
|
Directives,
|
||||||
|
Exposed,
|
||||||
|
Provide
|
||||||
>,
|
>,
|
||||||
I,
|
I,
|
||||||
S
|
S,
|
||||||
|
Exposed
|
||||||
>
|
>
|
||||||
|
|
||||||
|
export type ExposedKeys<
|
||||||
|
T,
|
||||||
|
Exposed extends string & keyof T,
|
||||||
|
> = '' extends Exposed ? T : Pick<T, Exposed>
|
||||||
|
|
||||||
// public properties exposed on the proxy, which is used as the render context
|
// public properties exposed on the proxy, which is used as the render context
|
||||||
// in templates (as `this` in the render option)
|
// in templates (as `this` in the render option)
|
||||||
export type ComponentPublicInstance<
|
export type ComponentPublicInstance<
|
||||||
|
@ -210,6 +232,7 @@ export type ComponentPublicInstance<
|
||||||
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>,
|
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>,
|
||||||
I extends ComponentInjectOptions = {},
|
I extends ComponentInjectOptions = {},
|
||||||
S extends SlotsType = {},
|
S extends SlotsType = {},
|
||||||
|
Exposed extends string = '',
|
||||||
> = {
|
> = {
|
||||||
$: ComponentInternalInstance
|
$: ComponentInternalInstance
|
||||||
$data: D
|
$data: D
|
||||||
|
@ -233,13 +256,16 @@ export type ComponentPublicInstance<
|
||||||
: (...args: any) => any,
|
: (...args: any) => any,
|
||||||
options?: WatchOptions,
|
options?: WatchOptions,
|
||||||
): WatchStopHandle
|
): WatchStopHandle
|
||||||
} & IfAny<P, P, Omit<P, keyof ShallowUnwrapRef<B>>> &
|
} & ExposedKeys<
|
||||||
|
IfAny<P, P, Omit<P, keyof ShallowUnwrapRef<B>>> &
|
||||||
ShallowUnwrapRef<B> &
|
ShallowUnwrapRef<B> &
|
||||||
UnwrapNestedRefs<D> &
|
UnwrapNestedRefs<D> &
|
||||||
ExtractComputedReturns<C> &
|
ExtractComputedReturns<C> &
|
||||||
M &
|
M &
|
||||||
ComponentCustomProperties &
|
ComponentCustomProperties &
|
||||||
InjectToObject<I>
|
InjectToObject<I>,
|
||||||
|
Exposed
|
||||||
|
>
|
||||||
|
|
||||||
export type PublicPropertiesMap = Record<
|
export type PublicPropertiesMap = Record<
|
||||||
string,
|
string,
|
||||||
|
|
|
@ -26,19 +26,29 @@ import { mapCompatDirectiveHook } from './compat/customDirective'
|
||||||
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
||||||
import { traverse } from './apiWatch'
|
import { traverse } from './apiWatch'
|
||||||
|
|
||||||
export interface DirectiveBinding<V = any> {
|
export interface DirectiveBinding<
|
||||||
|
Value = any,
|
||||||
|
Modifiers extends string = string,
|
||||||
|
Arg extends string = string,
|
||||||
|
> {
|
||||||
instance: ComponentPublicInstance | null
|
instance: ComponentPublicInstance | null
|
||||||
value: V
|
value: Value
|
||||||
oldValue: V | null
|
oldValue: Value | null
|
||||||
arg?: string
|
arg?: Arg
|
||||||
modifiers: DirectiveModifiers
|
modifiers: DirectiveModifiers<Modifiers>
|
||||||
dir: ObjectDirective<any, V>
|
dir: ObjectDirective<any, Value>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DirectiveHook<T = any, Prev = VNode<any, T> | null, V = any> = (
|
export type DirectiveHook<
|
||||||
el: T,
|
HostElement = any,
|
||||||
binding: DirectiveBinding<V>,
|
Prev = VNode<any, HostElement> | null,
|
||||||
vnode: VNode<any, T>,
|
Value = any,
|
||||||
|
Modifiers extends string = string,
|
||||||
|
Arg extends string = string,
|
||||||
|
> = (
|
||||||
|
el: HostElement,
|
||||||
|
binding: DirectiveBinding<Value, Modifiers, Arg>,
|
||||||
|
vnode: VNode<any, HostElement>,
|
||||||
prevVNode: Prev,
|
prevVNode: Prev,
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
|
@ -47,25 +57,52 @@ export type SSRDirectiveHook = (
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
) => Data | undefined
|
) => Data | undefined
|
||||||
|
|
||||||
export interface ObjectDirective<T = any, V = any> {
|
export interface ObjectDirective<
|
||||||
created?: DirectiveHook<T, null, V>
|
HostElement = any,
|
||||||
beforeMount?: DirectiveHook<T, null, V>
|
Value = any,
|
||||||
mounted?: DirectiveHook<T, null, V>
|
Modifiers extends string = string,
|
||||||
beforeUpdate?: DirectiveHook<T, VNode<any, T>, V>
|
Arg extends string = string,
|
||||||
updated?: DirectiveHook<T, VNode<any, T>, V>
|
> {
|
||||||
beforeUnmount?: DirectiveHook<T, null, V>
|
created?: DirectiveHook<HostElement, null, Value, Modifiers, Arg>
|
||||||
unmounted?: DirectiveHook<T, null, V>
|
beforeMount?: DirectiveHook<HostElement, null, Value, Modifiers, Arg>
|
||||||
|
mounted?: DirectiveHook<HostElement, null, Value, Modifiers, Arg>
|
||||||
|
beforeUpdate?: DirectiveHook<
|
||||||
|
HostElement,
|
||||||
|
VNode<any, HostElement>,
|
||||||
|
Value,
|
||||||
|
Modifiers,
|
||||||
|
Arg
|
||||||
|
>
|
||||||
|
updated?: DirectiveHook<
|
||||||
|
HostElement,
|
||||||
|
VNode<any, HostElement>,
|
||||||
|
Value,
|
||||||
|
Modifiers,
|
||||||
|
Arg
|
||||||
|
>
|
||||||
|
beforeUnmount?: DirectiveHook<HostElement, null, Value, Modifiers, Arg>
|
||||||
|
unmounted?: DirectiveHook<HostElement, null, Value, Modifiers, Arg>
|
||||||
getSSRProps?: SSRDirectiveHook
|
getSSRProps?: SSRDirectiveHook
|
||||||
deep?: boolean
|
deep?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FunctionDirective<T = any, V = any> = DirectiveHook<T, any, V>
|
export type FunctionDirective<
|
||||||
|
HostElement = any,
|
||||||
|
V = any,
|
||||||
|
Modifiers extends string = string,
|
||||||
|
Arg extends string = string,
|
||||||
|
> = DirectiveHook<HostElement, any, V, Modifiers, Arg>
|
||||||
|
|
||||||
export type Directive<T = any, V = any> =
|
export type Directive<
|
||||||
| ObjectDirective<T, V>
|
HostElement = any,
|
||||||
| FunctionDirective<T, V>
|
Value = any,
|
||||||
|
Modifiers extends string = string,
|
||||||
|
Arg extends string = string,
|
||||||
|
> =
|
||||||
|
| ObjectDirective<HostElement, Value, Modifiers, Arg>
|
||||||
|
| FunctionDirective<HostElement, Value, Modifiers, Arg>
|
||||||
|
|
||||||
export type DirectiveModifiers = Record<string, boolean>
|
export type DirectiveModifiers<K extends string = string> = Record<K, boolean>
|
||||||
|
|
||||||
export function validateDirectiveName(name: string) {
|
export function validateDirectiveName(name: string) {
|
||||||
if (isBuiltInDirective(name)) {
|
if (isBuiltInDirective(name)) {
|
||||||
|
|
|
@ -248,6 +248,8 @@ export type {
|
||||||
SetupContext,
|
SetupContext,
|
||||||
ComponentCustomProps,
|
ComponentCustomProps,
|
||||||
AllowedComponentProps,
|
AllowedComponentProps,
|
||||||
|
GlobalComponents,
|
||||||
|
GlobalDirectives,
|
||||||
ComponentInstance,
|
ComponentInstance,
|
||||||
} from './component'
|
} from './component'
|
||||||
export type {
|
export type {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Note: this file is auto concatenated to the end of the bundled d.ts during
|
||||||
|
// build.
|
||||||
|
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
Teleport: DefineComponent<TeleportProps>
|
||||||
|
Suspense: DefineComponent<SuspenseProps>
|
||||||
|
KeepAlive: DefineComponent<KeepAliveProps>
|
||||||
|
BaseTransition: DefineComponent<BaseTransitionProps>
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,7 +43,7 @@ describe('runtime-dom: v-on directive', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it should support key modifiers and system modifiers', () => {
|
test('it should support key modifiers and system modifiers', () => {
|
||||||
const keyNames = ['ctrl', 'shift', 'meta', 'alt']
|
const keyNames = ['ctrl', 'shift', 'meta', 'alt'] as const
|
||||||
|
|
||||||
keyNames.forEach(keyName => {
|
keyNames.forEach(keyName => {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
|
|
|
@ -39,14 +39,17 @@ function onCompositionEnd(e: Event) {
|
||||||
|
|
||||||
const assignKey = Symbol('_assign')
|
const assignKey = Symbol('_assign')
|
||||||
|
|
||||||
type ModelDirective<T> = ObjectDirective<
|
type ModelDirective<T, Modifiers extends string = string> = ObjectDirective<
|
||||||
T & { [assignKey]: AssignerFn; _assigning?: boolean }
|
T & { [assignKey]: AssignerFn; _assigning?: boolean },
|
||||||
|
any,
|
||||||
|
Modifiers
|
||||||
>
|
>
|
||||||
|
|
||||||
// We are exporting the v-model runtime directly as vnode hooks so that it can
|
// We are exporting the v-model runtime directly as vnode hooks so that it can
|
||||||
// be tree-shaken in case v-model is never used.
|
// be tree-shaken in case v-model is never used.
|
||||||
export const vModelText: ModelDirective<
|
export const vModelText: ModelDirective<
|
||||||
HTMLInputElement | HTMLTextAreaElement
|
HTMLInputElement | HTMLTextAreaElement,
|
||||||
|
'trim' | 'number' | 'lazy'
|
||||||
> = {
|
> = {
|
||||||
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
||||||
el[assignKey] = getModelAssigner(vnode)
|
el[assignKey] = getModelAssigner(vnode)
|
||||||
|
@ -183,7 +186,7 @@ export const vModelRadio: ModelDirective<HTMLInputElement> = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
|
export const vModelSelect: ModelDirective<HTMLSelectElement, 'number'> = {
|
||||||
// <select multiple> value need to be deep traversed
|
// <select multiple> value need to be deep traversed
|
||||||
deep: true,
|
deep: true,
|
||||||
created(el, { value, modifiers: { number } }, vnode) {
|
created(el, { value, modifiers: { number } }, vnode) {
|
||||||
|
@ -363,3 +366,10 @@ export function initVModelForSSR() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type VModelDirective =
|
||||||
|
| typeof vModelText
|
||||||
|
| typeof vModelCheckbox
|
||||||
|
| typeof vModelSelect
|
||||||
|
| typeof vModelRadio
|
||||||
|
| typeof vModelDynamic
|
||||||
|
|
|
@ -1,33 +1,40 @@
|
||||||
import {
|
import {
|
||||||
type ComponentInternalInstance,
|
type ComponentInternalInstance,
|
||||||
DeprecationTypes,
|
DeprecationTypes,
|
||||||
|
type Directive,
|
||||||
type LegacyConfig,
|
type LegacyConfig,
|
||||||
compatUtils,
|
compatUtils,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { hyphenate, isArray } from '@vue/shared'
|
import { hyphenate, isArray } from '@vue/shared'
|
||||||
|
|
||||||
const systemModifiers = ['ctrl', 'shift', 'alt', 'meta']
|
const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'] as const
|
||||||
|
type SystemModifiers = (typeof systemModifiers)[number]
|
||||||
|
type CompatModifiers = keyof typeof keyNames
|
||||||
|
|
||||||
|
export type VOnModifiers = SystemModifiers | ModifierGuards | CompatModifiers
|
||||||
type KeyedEvent = KeyboardEvent | MouseEvent | TouchEvent
|
type KeyedEvent = KeyboardEvent | MouseEvent | TouchEvent
|
||||||
|
|
||||||
const modifierGuards: Record<
|
const modifierGuards = {
|
||||||
string,
|
stop: (e: Event) => e.stopPropagation(),
|
||||||
(e: Event, modifiers: string[]) => void | boolean
|
prevent: (e: Event) => e.preventDefault(),
|
||||||
> = {
|
self: (e: Event) => e.target !== e.currentTarget,
|
||||||
stop: e => e.stopPropagation(),
|
ctrl: (e: Event) => !(e as KeyedEvent).ctrlKey,
|
||||||
prevent: e => e.preventDefault(),
|
shift: (e: Event) => !(e as KeyedEvent).shiftKey,
|
||||||
self: e => e.target !== e.currentTarget,
|
alt: (e: Event) => !(e as KeyedEvent).altKey,
|
||||||
ctrl: e => !(e as KeyedEvent).ctrlKey,
|
meta: (e: Event) => !(e as KeyedEvent).metaKey,
|
||||||
shift: e => !(e as KeyedEvent).shiftKey,
|
left: (e: Event) => 'button' in e && (e as MouseEvent).button !== 0,
|
||||||
alt: e => !(e as KeyedEvent).altKey,
|
middle: (e: Event) => 'button' in e && (e as MouseEvent).button !== 1,
|
||||||
meta: e => !(e as KeyedEvent).metaKey,
|
right: (e: Event) => 'button' in e && (e as MouseEvent).button !== 2,
|
||||||
left: e => 'button' in e && (e as MouseEvent).button !== 0,
|
|
||||||
middle: e => 'button' in e && (e as MouseEvent).button !== 1,
|
|
||||||
right: e => 'button' in e && (e as MouseEvent).button !== 2,
|
|
||||||
exact: (e, modifiers) =>
|
exact: (e, modifiers) =>
|
||||||
systemModifiers.some(m => (e as any)[`${m}Key`] && !modifiers.includes(m)),
|
systemModifiers.some(m => (e as any)[`${m}Key`] && !modifiers.includes(m)),
|
||||||
}
|
} satisfies Record<
|
||||||
|
string,
|
||||||
|
| ((e: Event) => void | boolean)
|
||||||
|
| ((e: Event, modifiers: string[]) => void | boolean)
|
||||||
|
>
|
||||||
|
|
||||||
|
type ModifierGuards = keyof typeof modifierGuards
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
|
@ -36,7 +43,7 @@ export const withModifiers = <
|
||||||
T extends (event: Event, ...args: unknown[]) => any,
|
T extends (event: Event, ...args: unknown[]) => any,
|
||||||
>(
|
>(
|
||||||
fn: T & { _withMods?: { [key: string]: T } },
|
fn: T & { _withMods?: { [key: string]: T } },
|
||||||
modifiers: string[],
|
modifiers: VOnModifiers[],
|
||||||
) => {
|
) => {
|
||||||
const cache = fn._withMods || (fn._withMods = {})
|
const cache = fn._withMods || (fn._withMods = {})
|
||||||
const cacheKey = modifiers.join('.')
|
const cacheKey = modifiers.join('.')
|
||||||
|
@ -44,7 +51,7 @@ export const withModifiers = <
|
||||||
cache[cacheKey] ||
|
cache[cacheKey] ||
|
||||||
(cache[cacheKey] = ((event, ...args) => {
|
(cache[cacheKey] = ((event, ...args) => {
|
||||||
for (let i = 0; i < modifiers.length; i++) {
|
for (let i = 0; i < modifiers.length; i++) {
|
||||||
const guard = modifierGuards[modifiers[i]]
|
const guard = modifierGuards[modifiers[i] as ModifierGuards]
|
||||||
if (guard && guard(event, modifiers)) return
|
if (guard && guard(event, modifiers)) return
|
||||||
}
|
}
|
||||||
return fn(event, ...args)
|
return fn(event, ...args)
|
||||||
|
@ -54,7 +61,7 @@ export const withModifiers = <
|
||||||
|
|
||||||
// Kept for 2.x compat.
|
// Kept for 2.x compat.
|
||||||
// Note: IE11 compat for `spacebar` and `del` is removed for now.
|
// Note: IE11 compat for `spacebar` and `del` is removed for now.
|
||||||
const keyNames: Record<string, string | string[]> = {
|
const keyNames = {
|
||||||
esc: 'escape',
|
esc: 'escape',
|
||||||
space: ' ',
|
space: ' ',
|
||||||
up: 'arrow-up',
|
up: 'arrow-up',
|
||||||
|
@ -62,7 +69,7 @@ const keyNames: Record<string, string | string[]> = {
|
||||||
right: 'arrow-right',
|
right: 'arrow-right',
|
||||||
down: 'arrow-down',
|
down: 'arrow-down',
|
||||||
delete: 'backspace',
|
delete: 'backspace',
|
||||||
}
|
} satisfies Record<string, string | string[]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
|
@ -101,7 +108,13 @@ export const withKeys = <T extends (event: KeyboardEvent) => any>(
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventKey = hyphenate(event.key)
|
const eventKey = hyphenate(event.key)
|
||||||
if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
|
if (
|
||||||
|
modifiers.some(
|
||||||
|
k =>
|
||||||
|
k === eventKey ||
|
||||||
|
keyNames[k as unknown as CompatModifiers] === eventKey,
|
||||||
|
)
|
||||||
|
) {
|
||||||
return fn(event)
|
return fn(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,3 +146,5 @@ export const withKeys = <T extends (event: KeyboardEvent) => any>(
|
||||||
}) as T)
|
}) as T)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type VOnDirective = Directive<any, any, VOnModifiers>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import {
|
import {
|
||||||
type App,
|
type App,
|
||||||
type CreateAppFunction,
|
type CreateAppFunction,
|
||||||
|
type DefineComponent,
|
||||||
DeprecationTypes,
|
DeprecationTypes,
|
||||||
|
type Directive,
|
||||||
type ElementNamespace,
|
type ElementNamespace,
|
||||||
type HydrationRenderer,
|
type HydrationRenderer,
|
||||||
type Renderer,
|
type Renderer,
|
||||||
|
@ -25,6 +27,11 @@ import {
|
||||||
isSVGTag,
|
isSVGTag,
|
||||||
isString,
|
isString,
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
|
import type { TransitionProps } from './components/Transition'
|
||||||
|
import type { TransitionGroupProps } from './components/TransitionGroup'
|
||||||
|
import type { vShow } from './directives/vShow'
|
||||||
|
import type { VOnDirective } from './directives/vOn'
|
||||||
|
import type { VModelDirective } from './directives/vModel'
|
||||||
|
|
||||||
declare module '@vue/reactivity' {
|
declare module '@vue/reactivity' {
|
||||||
export interface RefUnwrapBailTypes {
|
export interface RefUnwrapBailTypes {
|
||||||
|
@ -32,6 +39,22 @@ declare module '@vue/reactivity' {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
interface GlobalComponents {
|
||||||
|
Transition: DefineComponent<TransitionProps>
|
||||||
|
TransitionGroup: DefineComponent<TransitionGroupProps>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GlobalDirectives {
|
||||||
|
vShow: typeof vShow
|
||||||
|
vOn: VOnDirective
|
||||||
|
vBind: VModelDirective
|
||||||
|
vIf: Directive<any, boolean>
|
||||||
|
VOnce: Directive
|
||||||
|
VSlot: Directive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps)
|
const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps)
|
||||||
|
|
||||||
// lazy create the renderer - this makes core renderer logic tree-shakable
|
// lazy create the renderer - this makes core renderer logic tree-shakable
|
||||||
|
|
|
@ -292,7 +292,7 @@ describe('INSTANCE_SCOPED_SLOTS', () => {
|
||||||
components: {
|
components: {
|
||||||
child: {
|
child: {
|
||||||
compatConfig: { RENDER_FUNCTION: false },
|
compatConfig: { RENDER_FUNCTION: false },
|
||||||
render() {
|
render(this: LegacyPublicInstance) {
|
||||||
normalSlots = this.$slots
|
normalSlots = this.$slots
|
||||||
scopedSlots = this.$scopedSlots
|
scopedSlots = this.$scopedSlots
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue