我正在将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;
也不起作用,因为数据将是不确定的,因此不会是被动的。
我不想关闭打字稿检查,因为它们对于代码的其他部分很有用。
这里是否有适当的方法来初始化数据?
答案 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;