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

时间:2019-04-16 19:08:16

标签: typescript vue.js vue-class-components

我正在将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>

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

  

属性或方法“数据”未在实例上定义,但   渲染期间引用

这是正常现象,如vue-class-component页面中所述,未定义的数据不会反射。我需要将数据初始化为null。此外,我收到此打字稿错误:

  

属性“数据”没有初始化程序,因此未明确分配   构造函数

所以我想这样做:

private data: Model = null;

但我收到此打字稿错误:

  

类型'null'不能分配给类型'模型'。

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

private data!: Model;

也不起作用,因为数据将是不确定的,因此不会是被动的。

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

这里是否有适当的方法来初始化数据?

2 个答案:

答案 0 :(得分:3)

此类属性的正确类型是:

private data: Model | null = null;

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

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

或非null断言运算符:

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

一种解决方法是用断言欺骗输入系统:

private data: Model = null as unknown as Model;

vue-class-component不考虑TypeScript是因为undefined is easier to handle in TypeScript than null,尤其是因为这将允许将属性标记为可选。

  

我知道数据永远不会为空。

在安装组件之前将是null,这会留出错误的余地:

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

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

答案 1 :(得分:1)

假设数据是在创建时在商店中设置的,则可以使用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将永远不会被定义,因为它将返回_data或将_data设置为当前商店内容,然后返回该内容。
如果_data是基元而不是对象,并且计算结果为false(例如,(数字)0或(字符串)""),则此操作可能会失败。在这种情况下,请使用this._data === undefined而不是!this._data

您还可以将吸气剂缩短为

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

但这并不清楚,特别是如果读者不知道分配将返回所分配的值/引用,更糟糕的是使用原始类型进行读取:

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