We've built a project for the last 8 months using vue 3 and and the class components, but as it seems like it's no longer maintained, we'd like to gradually switch to the composition API, and more precisely to the setup script syntax.
We are currently using vue3.0.0 and vue-class-components 8.0.0.
Our goal would be, as we have to keep adding new features to the project, to start creating the new components with the composition API, while keeping those already written with vue class component. And, as we go along, we'll try to rewrite them with the composition API.
I tried to create a simple HelloWorld component using vue class components :
<template>
<div>
<TestComponent :test="'test string'" />
</div>
</template>
<script lang="ts">
import { Options, Vue } from 'vue-class-component';
import TestComponent from './TestComponent.vue';
@Options({
components: { TestComponent }
})
export default class HelloWorld extends Vue {
}
</script>
and add a test component :
<template>
<h1>Test composant {{ test }}</h1>
</template>
<script lang="ts">
export default {
name: 'TestComponent',
props: { test: String, required: true },
setup(props: { test: string }, context: unknown) { console.log(context); return { test: props.test } }
}
</script>
However, I come up with an error in my code : when declaring the TestComponent in the HelloWorld, the compiler tells me that he's expecting the argument 'test' as declared in the TestComponent :
Argument of type '{ name: string; props: { test: StringConstructor; required: boolean; }; setup(props: { test: string; }, context: unknown): { test: string; }; }' is not assignable to parameter of type 'Component<any, any, any, ComputedOptions, MethodOptions>'.
Type '{ name: string; props: { test: StringConstructor; required: boolean; }; setup(props: { test: string; }, context: unknown): { test: string; }; }' is not assignable to type 'ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any>'.
Type '{ name: string; props: { test: StringConstructor; required: boolean; }; setup(props: { test: string; }, context: unknown): { test: string; }; }' is not assignable to type 'ComponentOptionsBase<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}>'.
Types of property 'setup' are incompatible.
Type '(props: { test: string; }, context: unknown) => { test: string; }' is not assignable to type '(this: void, props: Readonly<LooseRequired<any>>, ctx: SetupContext<any>) => any'.
Types of parameters 'props' and 'props' are incompatible.
Property 'test' is missing in type 'Readonly<LooseRequired<any>>' but required in type '{ test: string; }'.ts(2345)
TestComponent.vue.ts(5, 18): 'test' is declared here.
UPDATE : I tried to register the TestComponent globally in the main.ts, but the error is still the same
Is there a way to make the two work together?
CodePudding user response:
Please note that :test
is a syntactic sugar for v-bind:test
, meaning if you don't have a reactive variable binding for :test
, you should use test
instead. See below:
// note there is no colon before test, which means you are just passing a constant string.
<TestComponent test="test string" />
CodePudding user response:
One issue is your props
declaration is incorrect. It should be:
// ❌ invalid
// props: {
// test: String,
// required: true
// },
props: {
test: {
type: String,
required: true
}
},
Also you don't need to type the arguments of setup()
, as they are normally inferred from the defineComponent()
utility, which enables type inference in Vue components:
// export default {
// setup(props: { test: string }, context: unknown) { /*...*/ }
// }
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, context) { /*...*/ }
})