facing-dev/vue-facing-decorator

Multi class inheritance in separate files

zub0r opened this issue ยท 7 comments

zub0r commented

Hi, I've tried the multi class example from the docs and it works when all classes are in single file.
Then I tried to separate classes into multiple files, but it stopped working.
Any suggestion would by highly appreciated.

https://stackblitz.com/edit/vue-1ntajv?file=src%2Fcomponents%2FComp.vue

zub0r commented

nevermind - removing the extra toNative fixed it

zub0r commented

Okay, so I can reconfirm that separating the files from the example results in error using "@vue/cli-service": "~5.0.0"
The error: Class extends value #<Object> is not a constructor or null

zub0r commented

Extending from multiple components also throws an error after separating to multiple files:
Cannot convert undefined or null to object at Function.getOwnPropertyDescriptor (<anonymous>)

Comp.vue:

<template>comp </template>
<script lang="ts">
import {
  Component, mixins, toNative,
} from 'vue-facing-decorator';
import ComponentA from './A.vue';
import ComponentB from './B.vue';

@Component({
  name: 'MyComponent',
})
class MyComponent extends mixins(ComponentA, ComponentB) {

}

export default toNative(MyComponent);

</script>

A.vue:

<script lang="ts">
import {
  Component, Vue,
} from 'vue-facing-decorator';

@Component({
  name: 'ComponentA',
})
export default class ComponentA extends Vue {

}
</script>

zub0r commented

Looks like the class you extend from needs to be in .ts file instead of .vue, then it works fine.

Hatzen commented

For me this error appeared after upgrading from ^2.1.20 to ^3.0.2 downgrading fixed the problem.

@Hatzen Could you share a test project?

This happens because the toNative method creates an object, not a class, thus you cannot extend from it.

I managed to solve this by exporting the base class like this:

@Component
class Base {
...
}

export { Base } // This exports the class
export default toNative(Base); // This exports the component

and then importing the Base like this in the child class:

import { Base } from "./Base.vue"

@Component
class Child extends Base {
...

And in case you want to import just the component itself, then you can do this:

import Base from "./Base.vue";