vue-class-component : 如何创建和初始化反射数据

vue-class-component : how to create and initialize reflective data

我将 vuejs 与 typescript 和 vue-class-component 一起使用。我正在尝试使用反应性数据创建自定义组件。

这是我的代码:

<template>
    <div>
        <input v-model="data.name" placeholder="Name">
        <input v-model="data.value" placeholder="Value">
    </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

interface Model {
    name: string;
    value: number;
}
@Component
export default class ClubVue extends Vue {
    private data: Model;

    public mounted() {
        this.data = {...this.$store.getters.data};
    }
}
</script>

在第一个版本中,我遇到了这个错误:

Property or method "data" is not defined on the instance but referenced during render

这很正常,在vue-class-component page里说了,undefined data不会被反射。我需要将数据初始化为空。此外,我收到此打字稿错误:

Property 'data' has no initializer and is not definitely assigned in the constructor

所以我想这样做:

private data: Model = null;

但是我收到这个打字稿错误:

Type 'null' is not assignable to type 'Model'.

我不想将数据类型更改为 Model | null,因为我将不得不在我将要使用它的任何地方检查数据是否为空,而且我知道数据永远不会为空。

private data!: Model;

也不起作用,因为数据将是未定义的,因此不会反应。

我不想关闭打字稿检查,因为它们对代码的其他部分很有用。

这里有初始化数据的正确方法吗?

这种 属性 的正确类型是:

private data: Model | null = null;

它可以与类型保护一起使用:

if (this.data) {
  console.log(this.data.name); // Model
}

或non-null断言运算符:

console.log(this.data!.name); // Model

解决方法是使用断言来欺骗打字系统:

private data: Model = null as unknown as Model;

vue-class-component 不考虑 TypeScript,因为 ,特别是因为这允许将 属性 标记为可选。

I know that data will never be null.

在挂载组件之前会是null,这就留下了错误的余地:

public created() {
    console.log(this.data.name); // runtime error but no compilation error
}

public mounted() {
    this.data = {...this.$store.getters.data};
}

您可以使用 getter 而不是直接分配数据,假设数据是在创建时在商店中设置的。确保您的商店 getter 类型安全!

@Component
export default class ClubVue extends Vue {
    private _data: Model | undefined;

    get data(): Model {
        if (!this._data) {
            this._data = {...this.$store.getters.data};
        }
        return this._data;
    }
}

这样,data 将永远不会未定义,因为它会 return _data 或将 _data 设置为当前存储内容,然后 return 那.
如果 _data 是原始对象而不是对象,并且计算结果为 false(例如(数字)0 或(字符串)""),这可能会失败。在这种情况下,请使用 this._data === undefined 而不是 !this._data

您也可以将 getter 缩短为

get data():Model {
    return this._data = this._data || {...this.$store.getters.data};
}

但这不太清楚,特别是如果 reader 不知道赋值将 return 正在赋值的 value/reference,更糟糕的是用原始类型读取:

return this._data = 
    this._data === undefined 
        ? {...this.$store.getters.data} 
        : this._data;