vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.81k stars 431 forks source link

"TypeError: Class extends value #<Object> is not a constructor or null" when extending components with Options API #603

Closed kpturner closed 2 years ago

kpturner commented 2 years ago

It does not seem to work well for me. If every component extends Vue the it is OK, but if you have a project (like an old Vue 2 project that you are migrating) where Component A is extended by Component B the it fails at run time with Uncaught TypeError: Class extends value #<Object> is not a constructor or null

It is easy to reproduce. I just created a simple Vue 3 app using Vite. Add a component like this

<template>
  <div class="greetings">
    <h1 class="green">{{ msg }}</h1>
    <h3>
      This is the class component
    </h3>
  </div>
</template>

<script lang="ts">

import { Vue, Options } from 'vue-class-component';

@Options({
    name: 'ClassComponentExtends',
    components: {
    }
})
export default class ClassComponentExtends extends Vue {
}

</script>

Then create another component that extends it

<script lang="ts">

import { Options } from 'vue-class-component';
import ClassComponentExtends from './ClassComponentExtends.vue';

@Options({
    name: 'ClassComponent',
    components: {
    }
})
export default class ClassComponent extends ClassComponentExtends {
}

</script>

Then use ClassComponent in your app somewhere. It will fail with the error defined above.

xEsk commented 2 years ago

Solution: https://github.com/vuejs/vue-class-component/issues/602#issuecomment-1075345146

The base clase should be a .ts and not a .vue file.

kpturner commented 2 years ago

It cannot be a .ts file if it contains an HTML template and some CSS. That is the problem. This is a base vue component and when you extend it (in Vue 2 at least) those that extend it inherit the template and styling.

kpturner commented 2 years ago

I guess I will just have to refactor the code to split out the script