ウェブサイト検索

vue.js - なぜ getter/setter が vue の TypeScript クラスコンポーネントで正しく動作しないのか


私は vue.js に不慣れで、次のコードが期待通りに動作しないのはなぜか疑問に思っています:

<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>

私が「Datum」を変更すると、dateChanged() メソッドが実行され、そのセッターで _timespan プロパティが設定されます。しかし、GUI は更新されません。セッター/ゲッターを取り除いて _timespan プロパティを直接使用すると、すべて正常に動作します。私は、セッター/ゲッター、つまり計算プロパティでも同じように動作するはずだと思うのですが、そうではないでしょうか?

回答 #1

わかりました、動作させることができました。主な問題は、定義したクラスがランタイムにはまったく存在しないことです。vue-class-component プラグインは定義を使用して、それに基づいた Vue コンポーネントを作成するだけです。だから this は見た目通りではありません。プラグインはプロパティをデータプロパティとして追加し、getter/setter を計算プロパティとして追加します。しかし、アンダースコアで始まるプロパティは追加しないようです。Owl がコメントで指摘していたように、これは vue-class-component の問題ではなく、ドキュメントにある Vue の挙動です: https://v2.vuejs.org/v2/api/#data とにかく、コードを次のように変更すれば動作します:

    @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
        }

    }

先頭にアンダースコアを付けずにプロパティに別の名前を付けると、うまくいきます。

でも、もう vue-class-component プラグインは使わないと思います。私には考えることが多すぎます。