Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
ComputedOptions,
ComponentPropsOptions,
ComponentOptions,
ConcreteComponent
ConcreteComponent,
Prop
} from 'vue'

import { MountingOptions, Slot } from './types'
Expand Down Expand Up @@ -73,6 +74,25 @@ function getInstanceOptions(
return resultOptions
}

// Class component (without vue-class-component) - no props
export function mount<V>(
originalComponent: {
new (...args: any[]): V
__vccOpts: any
},
options?: MountingOptions<any> & Record<string, any>
): VueWrapper<ComponentPublicInstance<V>>

// Class component (without vue-class-component) - props
export function mount<V, P>(
originalComponent: {
new (...args: any[]): V
__vccOpts: any
defaultProps?: Record<string, Prop<any>> | string[]
},
options?: MountingOptions<P & PublicProps> & Record<string, any>
): VueWrapper<ComponentPublicInstance<V>>

// Class component - no props
export function mount<V>(
originalComponent: {
Expand Down
83 changes: 81 additions & 2 deletions test-dts/mount.d-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { expectError, expectType } from './index'
import {
ComponentOptions,
DefineComponent,
defineComponent,
FunctionalComponent
FunctionalComponent,
getCurrentInstance,
h,
ref,
SetupContext,
Prop,
VNodeChild
} from 'vue'
import { Options, Vue } from 'vue-class-component'
import { mount } from '../src'
Expand Down Expand Up @@ -179,7 +186,7 @@ declare const FunctionalComponentEmit: FunctionalComponent<
level: number
},
{ hello: (foo: string, bar: string) => void }
>
>

mount(FunctionalComponent)
mount(defineComponent(FunctionalComponent))
Expand Down Expand Up @@ -211,6 +218,78 @@ class ClassComponent extends Vue {
expectError(mount(ClassComponent, {}).vm.changeMessage())
mount(ClassComponent, {}).vm.changeMessage('')

// region custom class component implement
class CustomClassComponent<Props extends {} = {}> {
static defaultProps?: Record<string, Prop<any>> | string[]
private static __vccValue?: ComponentOptions
static get __vccOpts(): ComponentOptions {
if (this.__vccValue) return this.__vccValue
const CompConstructor = this
return (this.__vccValue = {
name: CompConstructor.name,
props: CompConstructor.defaultProps,
setup(props, ctx) {
const instance = new CompConstructor()
return instance.render.bind(instance)
}
})
}
constructor() {
const instance = getCurrentInstance()!
this.props = instance.props as Props
// @ts-expect-error no explicit setupContext on instance
this.context = instance.setupContext as SetupContext
}

props: Props
get $props() {
return this.props
}
context: SetupContext
render(): VNodeChild {}
}
class NoPropCustomClassComponent extends CustomClassComponent {
count = ref(0)
changeCount(count: number) {
this.count.value = count
}
render() {
return h('div', `hello world ${this.count.value}`)
}
}

// @ts-expect-error changeCount expects an argument
expectError(mount(NoPropCustomClassComponent, {}).vm.changeCount())
mount(NoPropCustomClassComponent, {}).vm.changeCount(2)

interface CustomClassComponentProps {
size: 'small' | 'large'
age?: number
}

class WithPropCustomClassComponent extends CustomClassComponent<CustomClassComponentProps> {
static defaultProps: (keyof CustomClassComponentProps)[] = ['size', 'age']
count = ref(0)
changeCount(count: number) {
this.count.value = count
}
render() {
return h('div', `hello world ${this.count.value}${this.props.size}`)
}
}

expectError(
// @ts-expect-error should has props error
mount<WithPropCustomClassComponent, CustomClassComponentProps>(WithPropCustomClassComponent, {
props: {}
})
)
mount<WithPropCustomClassComponent, CustomClassComponentProps>(WithPropCustomClassComponent, {
props: { size: 'small' }
})

// endregion

// default props
const Foo = defineComponent({
props: {
Expand Down