Skip to content

Commit f4c20bf

Browse files
committed
fix: support class component
1 parent ed07b50 commit f4c20bf

File tree

6 files changed

+51
-5
lines changed

6 files changed

+51
-5
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@
3333
"jsdom-global": "^3.0.2",
3434
"lint-staged": "^10.0.9",
3535
"prettier": "^2.0.2",
36+
"reflect-metadata": "^0.1.13",
3637
"rollup": "^1.31.1",
3738
"rollup-plugin-typescript2": "^0.26.0",
3839
"ts-jest": "25.2.1",
3940
"tsd": "0.11.0",
4041
"typescript": "^3.7.5",
4142
"vue": "^3.0.2",
43+
"vue-class-component": "^8.0.0-beta.4",
4244
"vue-jest": "^5.0.0-alpha.5",
4345
"vue-router": "^4.0.0-rc.1",
4446
"vuex": "^4.0.0-beta.4"

src/mount.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ import {
2626

2727
import { config } from './config'
2828
import { GlobalMountOptions } from './types'
29-
import { mergeGlobalProperties } from './utils'
29+
import { isClassComponent, mergeGlobalProperties } from './utils'
3030
import { processSlot } from './utils/compileSlots'
3131
import { createWrapper, VueWrapper } from './vueWrapper'
3232
import { attachEmitListener } from './emitMixin'
3333
import { createDataMixin } from './dataMixin'
3434
import { MOUNT_COMPONENT_REF, MOUNT_PARENT_NAME } from './constants'
3535
import { stubComponents } from './stubs'
36+
import { VueConstructor } from 'vue-class-component'
3637

3738
// NOTE this should come from `vue`
3839
type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps
@@ -67,6 +68,12 @@ export type ObjectEmitsOptions = Record<
6768
>
6869
export type EmitsOptions = ObjectEmitsOptions | string[]
6970

71+
// Class component
72+
export function mount(
73+
originalComponent: VueConstructor,
74+
options?: MountingOptions<any>
75+
): VueWrapper<ComponentPublicInstance<any>>
76+
7077
// Functional component with emits
7178
export function mount<Props, E extends EmitsOptions = {}>(
7279
originalComponent: FunctionalComponent<Props, E>,
@@ -224,11 +231,11 @@ export function mount(
224231
options?: MountingOptions<any>
225232
): VueWrapper<any> {
226233
// normalise the incoming component
227-
let component
234+
let component = originalComponent
228235

229236
const functionalComponentEmits: Record<string, unknown[]> = {}
230237

231-
if (typeof originalComponent === 'function') {
238+
if (typeof originalComponent === 'function' && !isClassComponent(component)) {
232239
// we need to wrap it like this so we can capture emitted events.
233240
// we capture events using a mixin that mutates `emit` in `beforeCreate`,
234241
// but functional components do not support mixins, so we need to wrap it
@@ -240,8 +247,6 @@ export function mount(
240247
)
241248
}
242249
})
243-
} else {
244-
component = { ...originalComponent }
245250
}
246251

247252
const el = document.createElement('div')

src/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ export const mergeDeep = (
6464

6565
return target
6666
}
67+
68+
export function isClassComponent(component: any) {
69+
return '__vccBase' in component
70+
}

tests/features/classComponent.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'reflect-metadata'
2+
import { h } from 'vue'
3+
import { Options, Vue } from 'vue-class-component'
4+
import { mount } from '../../src'
5+
6+
test('data: $props should be available', () => {
7+
@Options({
8+
props: ['foo']
9+
})
10+
class MyComp extends Vue {
11+
message = 'answer is ' + (this.$props as any).foo
12+
render() {
13+
return h('div', this.message)
14+
}
15+
}
16+
17+
const wrapper = mount(MyComp, {
18+
props: {
19+
foo: 42
20+
}
21+
})
22+
23+
expect(wrapper.html()).toBe('<div>answer is 42</div>')
24+
})

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"lib": ["DOM", "ES2015", "ES2017"],
77
"moduleResolution": "node",
88
"esModuleInterop": true,
9+
"experimentalDecorators": true,
910
"allowSyntheticDefaultImports": true,
1011
"baseUrl": ".",
1112
"paths": {

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5083,6 +5083,11 @@ redent@^2.0.0:
50835083
indent-string "^3.0.0"
50845084
strip-indent "^2.0.0"
50855085

5086+
reflect-metadata@^0.1.13:
5087+
version "0.1.13"
5088+
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
5089+
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
5090+
50865091
regenerate-unicode-properties@^8.2.0:
50875092
version "8.2.0"
50885093
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
@@ -6154,6 +6159,11 @@ [email protected]:
61546159
core-util-is "1.0.2"
61556160
extsprintf "^1.2.0"
61566161

6162+
vue-class-component@^8.0.0-beta.4:
6163+
version "8.0.0-beta.4"
6164+
resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-8.0.0-beta.4.tgz#bff95cdd44eb450a4a4e54b69da22099613d8071"
6165+
integrity sha512-+QXBhVH/Mz8dEC+IU7e8XXM54Tn0Aj9/saybeuK8XmhQiJlcijCB8kB7CYpBEMpHWaA+DoLr6LvHMbclYRCwZQ==
6166+
61576167
vue-jest@^5.0.0-alpha.5:
61586168
version "5.0.0-alpha.5"
61596169
resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-5.0.0-alpha.5.tgz#a24b7569ba2078836a316033f283e151afc4906b"

0 commit comments

Comments
 (0)