Skip to content

Commit

Permalink
fix: support for class component mixins (#334)
Browse files Browse the repository at this point in the history
Fix for using class component with mixins and also for importing
Vue from vue-property-decorator instead of vue-class-component.

Co-authored-by: Evert van der Weit <evert@mett.nl>
  • Loading branch information
Evertvdw and mett-development authored May 5, 2021
1 parent af80ab0 commit 76dfcad
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 4 deletions.
20 changes: 20 additions & 0 deletions e2e/__projects__/basic/components/ClassComponentProperty.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<div class="hello">
<h1 data-computed>{{ computedMsg }}</h1>
<h2 data-props>{{ msg }}</h2>
</div>
</template>

<script lang="ts">
import { Vue, Prop } from 'vue-property-decorator'
export default class ClassComponent extends Vue {
dataText: string = 'Hello'
@Prop() msg!: string
get computedMsg(): string {
return `Message: ${this.dataText}`
}
}
</script>
12 changes: 12 additions & 0 deletions e2e/__projects__/basic/components/ClassComponentWithMixin.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<div class="hello">
<h1 data-mixin>{{ message }}</h1>
</div>
</template>

<script lang="ts">
import { mixins } from 'vue-class-component'
import ClassMixin from './ClassMixin'
export default class ClassComponent extends mixins(ClassMixin) {}
</script>
5 changes: 5 additions & 0 deletions e2e/__projects__/basic/components/ClassMixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Vue } from 'vue-class-component'

export default class ClassMixin extends Vue {
message = 'Hello world!'
}
7 changes: 5 additions & 2 deletions e2e/__projects__/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@
"jest": "^26.0.0",
"ts-jest": "^26.4.4",
"typescript": "^4.1.2",
"vue-class-component": "^8.0.0-beta.4"
"vue-class-component": "^8.0.0-beta.4",
"vue-property-decorator": "^10.0.0-rc.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
"vue",
"ts"
],
"transform": {
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "../../../lib/index.js"
},
Expand Down
21 changes: 21 additions & 0 deletions e2e/__projects__/basic/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import Pug from './components/Pug.vue'
import Coffee from './components/Coffee.vue'
import Basic from './components/Basic.vue'
import ClassComponent from './components/ClassComponent.vue'
import ClassComponentWithMixin from './components/ClassComponentWithMixin.vue'
import ClassComponentProperty from './components/ClassComponentProperty.vue'
import TypeScript from './components/TypeScript.vue'
import jestVue from '../../../'
import RenderFunction from './components/RenderFunction.vue'
Expand Down Expand Up @@ -141,6 +143,25 @@ test('supports class component .vue files', () => {
})
})

test('supports class component .vue files with mixins', () => {
expect.assertions(1)
mount(ClassComponentWithMixin)
expect(document.querySelector('[data-mixin]').textContent).toBe(
'Hello world!'
)
})

test('supports class component .vue files using vue-property-decorator', () => {
expect.assertions(2)
mount(ClassComponentProperty, { msg: 'Props Message' })
expect(document.querySelector('[data-computed]').textContent).toBe(
'Message: Hello'
)
expect(document.querySelector('[data-props]').textContent).toBe(
'Props Message'
)
})

// TODO: How do functional components work in Vue 3?
xtest('processes functional components', () => {
// const clickSpy = jest.fn()
Expand Down
6 changes: 4 additions & 2 deletions lib/generate-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ module.exports = function generateCode(
var tempOutput = node.toString()

if (
tempOutput.match(/\}\(.*.?Vue\);/) &&
tempOutput.includes('vue-class-component')
// vue-property-decorator also exports Vue, which can be used to create a class component.
// In that case vue-class-component is not present in the tempOutput.
tempOutput.includes('vue-class-component') ||
tempOutput.includes('vue-property-decorator')
) {
node.add(`
;exports.default = {
Expand Down

1 comment on commit 76dfcad

@charrywong
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The matching rules of "vue-class-component" are too simple.
If this words exists in the vue file and not import format, the unit test will fail and the VM cannot be rendered.
Such it's a comments or a plain text;

<template> vue-class-component </template>

Please sign in to comment.