2

I'm new to vue.js and I'm wondering why the following code is not working as expected:

<template>
  <page-layout>
    <h1>Hello, Invoicer here</h1>
    <form class="invoicer-form">
      <div><label><span>Datum</span><input v-model="date" v-on:change="dateChanged" /></label></div>
      <div><label><span>Zeitraum</span><input v-model="timespan" /></label></div>
    </form>
  </page-layout>
</template>

<script lang="ts">
    import { Component, Prop, Vue } from 'vue-property-decorator'
    import PageLayout from '@/components/layout/PageLayout.vue'
    import dayjs from 'dayjs'
    import customParseFormat from 'dayjs/plugin/customParseFormat'

    @Component({
        components: { PageLayout }
    })
    export default class Invoicer extends Vue {

        date = ''
        _timespan = ''

        beforeCreate(): void {
            dayjs.extend(customParseFormat)
        }

        dateChanged(): void {
            const format = 'DD.MM.YYYY'
            const date = dayjs(this.date, format)
            if (date.isValid()) {
                if (!this.timespan) {
                    const from = date.subtract(1, 'month').startOf('month').format(format)
                    const until = date.endOf('month').format(format)
                    this.timespan = `${from} - ${until}`
                }
            }
        }

        get timespan(): string {
            return this._timespan
        }

        set timespan(value: string) {
            this._timespan = value
        }

    }
</script>

when I change the 'Datum' the dateChanged()-method is executed and sets the _timespan-property with its setter. But the GUI won't be updated. If I remove the setter/getter and use the _timespan`-property directly, everything works fine. I really think it should also work with the setter/getter or in other therms, computed property, shouldn't it?

2
  • 1
    why are you using getters and setters in the first place? Commented Apr 3, 2021 at 20:55
  • Maybe your approach conflicts with the TypeScript rules for getters and setters. Because they are thought to be used inside a plain Object. I am not sure wether a component is seen as this. Commented Apr 3, 2021 at 22:09

1 Answer 1

3

Ok, I got it working. The main problem is, the defined class isn't existing at all on runtime. The vue-class-component plugin just use the definition and creates a VueComponent based on it. So this isn't what it it seems to be. The plugin adds properties as data properties, getter/setter as computed properties. But it seems like it doesn't add properties starting with an underscore. Like Owl mentioned in his comment, this is not an vue-class-compnent issue but a documented vue behavior: https://v2.vuejs.org/v2/api/#data Anyhow, if I change the code as follows, it works:

    @Component({
        components: { PageLayout }
    })
    export default class Invoicer extends Vue {

        date = ''
        timesspan = ''

        beforeCreate(): void {
            dayjs.extend(customParseFormat)
        }

        dateChanged(): void {
            console.log("badsfls")
            const format = 'DD.MM.YYYY'
            const date = dayjs(this.date, format)
            if (date.isValid()) {
                if (!this.timespan) {
                    const from = date.subtract(1, 'month').startOf('month').format(format)
                    const until = date.endOf('month').format(format)
                    this.timespan = `${from} - ${until}`
                }
            }
        }

        get timespan(): string {
            return this.timesspan
        }

        set timespan(value: string) {
            this.timesspan = value
        }

    }

Giving the property an other name without leading underscore does the trick.

But I think I won't use the vue-class-component plugin anymore. It is too much around the corner thinking for me.

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

4 Comments

I don't like the vue-class-component either. Give a try to Vue3 with composition API, it now has TS support out of the box (Vue3 is written in TS) and the composition API feels a lot of better than the class appproach
That sounds very promising thanks for the tip. Vue will be used in the new Projekt I start working on next week. I'm not sure if using Vue 3 is already an option because of its beta state but first class typescript support makes trying it out absolutely worthy I think.
It isn't beta anymore, last year (September I think) it was moved to release state. I'm currently using it in a couple of projects and in my opinion is worth it.
Haven't tried your code but this seems to be a Vue issue, not vue-class-component issue, check this issue

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.