Skip to content

Print warning if class property is used without inheriting Vue class #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 11, 2016
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Note:
5. For all other options, pass them to the decorator function.

``` js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
Expand All @@ -38,7 +39,7 @@ import Component from 'vue-class-component'
</div>
`
})
class App {
class App extends Vue {
// initial data
msg = 123

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.18.0",
"chai": "^3.5.0",
"chai-spies": "^0.7.1",
"mocha": "^3.1.2",
"node-libs-browser": "^1.0.0",
"rimraf": "^2.5.4",
Expand Down
13 changes: 11 additions & 2 deletions src/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Vue from 'vue'
import { VueClass } from './declarations'
import { noop } from './util'
import { noop, warn } from './util'

export function collectDataFromConstructor (vm: Vue, Component: VueClass) {
// override _init to prevent to init as Vue instance
Expand All @@ -25,5 +25,14 @@ export function collectDataFromConstructor (vm: Vue, Component: VueClass) {
}
})

if (process.env.NODE_ENV !== 'production') {
if (!(Component.prototype instanceof Vue) && Object.keys(plainData).length > 0) {
warn(
'Component class must inherit Vue or its descendant class ' +
'when class property is used.'
)
}
}

return plainData
}
}
10 changes: 10 additions & 0 deletions src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* global type declarations in this project
* should not expose to userland
*/

declare const process: {
env: {
NODE_ENV: string
}
}
6 changes: 6 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ export function createDecorator (
$decoratorQueue.push(options => factory(options, key, index))
}
}

export function warn (message: string): void {
if (typeof console !== 'undefined') {
console.warn('[vue-class-component] ' + message)
}
}
42 changes: 38 additions & 4 deletions test/test-babel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import Component, { createDecorator } from '../lib/index'
import { expect } from 'chai'
import chai, { expect } from 'chai'
import spies from 'chai-spies'
import Vue from 'vue'

chai.use(spies)

describe('vue-class-component with Babel', () => {
it('should be instantiated without any errors', () => {
@Component
Expand All @@ -10,12 +13,21 @@ describe('vue-class-component with Babel', () => {
})

it('should collect class properties as data', () => {
@Component
class MyComp {
@Component({
props: ['propValue']
})
class MyComp extends Vue {
foo = 'hello'
bar = 1 + this.propValue
}
const c = new MyComp()
const c = new MyComp({
propsData: {
propValue: 1
}
})
expect(c.foo).to.equal('hello')
expect(c.propValue).to.equal(1)
expect(c.bar).to.equal(2)
})

it('should not collect uninitialized class properties', () => {
Expand All @@ -35,4 +47,26 @@ describe('vue-class-component with Babel', () => {
expect('foo' in c.$data).to.be.false
expect('bar' in c.$data).to.be.false
})

it('warn if class property is used without inheriting Vue class', () => {
const spy = chai.spy.on(console, 'warn')

@Component({
foo: Number
})
class MyComp {
bar = this.foo + 2
}
const c = new MyComp({
propsData: {
foo: 1
}
})

const message = '[vue-class-component] ' +
'Component class must inherit Vue or its descendant class ' +
'when class property is used.'

expect(spy).to.have.been.called.with(message)
})
})