为啥 getter/setter 在 vue typescript 类组件中无法正常工作

Posted

技术标签:

【中文标题】为啥 getter/setter 在 vue typescript 类组件中无法正常工作【英文标题】:why are getter/setter not working properly in vue typescript class component为什么 getter/setter 在 vue typescript 类组件中无法正常工作 【发布时间】:2021-06-30 07:02:50 【问题描述】:

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

当我更改“基准”时,dateChanged()-方法被执行并使用它的设置器设置_timespan-property。但是GUI不会更新。如果我删除 setter/getter 并直接使用 _timespan`-property,一切正常。我真的认为它也应该与 setter/getter 或其他热计算属性一起使用,不是吗?

【问题讨论】:

你为什么首先使用 getter 和 setter? 也许你的方法与 getter 和 setter 的 TypeScript 规则冲突。因为它们被认为是在普通对象中使用的。我不确定组件是否被视为这样。 【参考方案1】:

好的,我搞定了。主要问题是,定义的类在运行时根本不存在。 vue-class-component 插件只是使用定义并基于它创建一个 VueComponent。所以this 不是它看起来的样子。该插件将属性添加为数据属性,将 getter/setter 添加为计算属性。但它似乎没有添加以下划线开头的属性。就像 Owl 在他的评论中提到的那样,这不是 vue-class-compnent 问题,而是记录在案的 vue 行为:https://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 插件了。这对我来说太多了。

【讨论】:

我也不喜欢 vue-class-component。尝试使用 Vue3 的组合 API,它现在有开箱即用的 TS 支持(Vue3 是用 TS 编写的),组合 API 感觉比类方法好很多 这听起来很有希望,感谢您的提示。 Vue 将在我下周开始工作的新 Projekt 中使用。我不确定使用 Vue 3 是否已经是一个选项,因为它的 beta 状态,但一流的打字稿支持让我认为绝对值得尝试。 它不再是测试版了,去年(我认为是 9 月)它被转移到了发布状态。我目前在几个项目中使用它,在我看来是值得的。 没有试过你的代码,但这似乎是一个 Vue 问题,而不是vue-class-component 问题,请检查this issue

以上是关于为啥 getter/setter 在 vue typescript 类组件中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥 GSON 使用字段而不是 getter/setter?

vue-class-component 语法中 vue-models(因此,“props”)的计算 getter/setter

基于类的 vue 组件属性定义:构造函数 vs.getter/setter vs.mounted 生命周期

封装 - 为啥我使用 getter setter 将我的数据成员公开,如果我已经在课堂上声明它们是私有的

Vue数据绑定失效

axios请求给getter setter方法而不是查询数据