4

I'm currently working on a Vue 2 project with TS using these libraries for component setup : vue-class-component and vue-property-decorator

I need to create a form component, but I'm having a hard time with data binding, because when I use the data() option for my form component it produces errors on compile time.

Is there a way to bind input data without using the data() option ?

The errors I get :

ERROR in /path/to/components/folder/Form.vue

Property 'id' does not exist in type 'Form'.

For more context here's my code :

@Component
export default class Form extends Vue {
//Bind form data
data() {
    return {
        id: "",
        name: "",
        age: 0,
        amountA: 0,
        amountB: 0,
        capitalA: 0,
        capitalB: 0
    } 
}

onSubmit(e: any): void {
    e.preventDefault();
    //Create new class object
    const newClass = {
        id: this.id,
        name: this.name,
        age: this.age,
        amountA: this.amountA,
        amountB: this.amountB,
        capitalA: this.capitalA,
        capitalB: this.capitalB
    }

    //Emit the class object to parent component
    this.$emit("add-class", newClass);
    this.$emit("update-total");

    //Reset Form
    this.id = ""
    this.name = ""
    this.age = 0
    this.amountA = 0
    this.amountB = 0
    this.capitalA = 0
    this.capitalB = 0

}

And here's the error on my console: Console error

Can anyone helps me to get ride of these error. Thank you!

1 Answer 1

4

In Vue class component decorators, the Options API's data() function is abstracted away.

The @Component decorator is a function responsible for transpiling your code from Class API syntax into Options API syntax.

Namely, behind the scenes:

  • all class props are turned into data() reactive props,
  • all getters/setters are turned into computed props
  • all class methods (regular functions) are turned into methods.

So just declare the props directly on the class instance:

@Component
export default class Form extends Vue {
  id = "";
  name = "";
  age = 0;
  amountA = 0;
  amountB = 0;
  capitalA = 0;
  capitalB = 0;

  // props declared above are reactive and you can now use them
  // in getters or methods
}

See the example in the Overview page. In more detail, this particular comment:

// Class properties will be component data


Warning: If you're just picking up Vue, be warned Vue class decorators syntax is on a downwards usage trend and problems with Vue 3 compatibility are to be expected (and have already started to surface). Have a look at the open issues on their repo.

On the same note, you might want to read this comment by Evan You1, ref usage of Vue class component decorators:

It definitely isn't a recommended option anymore in official docs or default tooling (moving to Vite-based soon and vue-cli will be in maintenance mode).
Deprecation will depend on actual usage and @ktsn's2 intention on further working on the project.

1 :: author of Vue
2 :: maintainer of vue-class-component package


Personal advice: installing @vue/composition-api in your Vue 2 project and rewriting its components in Composition API syntax would be more beneficial than writing in class decorators syntax, to both yourself and the project.

In doing this, you'll

  • make it possible for the project to be upgraded to Vue 3 with relative ease
  • learn Composition API (likely to become the more common Vue syntax), which is more valuable for you, going forward, than learning the component class decorators syntax and workarounds, (likely to become less used, eventually deprecated)

Because the class decorators syntax is dropping in popularity, the support for it might become more difficult to obtain, as time passes.

If rewriting existing components in Composition API is not an option, you could at least write new components in this syntax, as the syntax is incrementally adoptable, it can be used alongside any other valid Vue API syntax.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi tao, first I would like to thank you for enlighten me! I will definitely take a closer and deeper look on the topic. I really appreciate all the details and the explanation. Finally, I did refactor my code and it works perfectly fine, like you said I have been mixing up the vue conventional way and the vue component way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.