vue-class-component:如何创建和初始化反射数据
Posted
技术标签:
【中文标题】vue-class-component:如何创建和初始化反射数据【英文标题】:vue-class-component : how to create and initialize reflective data 【发布时间】:2019-09-06 23:08:56 【问题描述】:我正在使用带有 typescript 和 vue-class-component 的 vuejs。我正在尝试使用反应数据创建自定义组件。
这是我的代码:
<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 页面中所说,未定义的数据不会反射。我需要将数据初始化为空。此外,我得到这个打字稿错误:
属性“数据”没有初始化器,也没有明确分配 构造函数
所以我想这样做:
private data: Model = null;
但我收到此打字稿错误:
类型“null”不可分配给类型“Model”。
我不想将数据类型更改为Model | null
,因为我必须检查数据是否在任何我使用它的地方都为空,而且我知道数据永远不会为空。
private data!: Model;
也不起作用,因为数据将是未定义的,因此不会是反应性的。
我不想关闭 typescript 检查,因为它们对代码的其他部分很有用。
这里有合适的初始化数据的方法吗?
【问题讨论】:
【参考方案1】:此类属性的正确类型是:
private data: Model | null = null;
它可以与类型保护一起使用:
if (this.data)
console.log(this.data.name); // Model
或非空断言运算符:
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;
【讨论】:
【参考方案2】:您可以使用 getter 而不是直接分配数据,假设数据在创建时已在 store 中设置。确保你的 store 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
。
你也可以将 getter 缩短为
get data():Model
return this._data = this._data || ...this.$store.getters.data;
但这不太清楚,特别是如果读者不知道赋值将返回被赋值的值/引用,甚至更糟糕的是使用原始类型读取:
return this._data =
this._data === undefined
? ...this.$store.getters.data
: this._data;
【讨论】:
我支持这种方法,但typeof(this._data) === 'undefined'
是多余的,this._data === undefined
更具可读性但也不必要,因为它可以是未定义的,也可以是这个 sn-p 中的对象。至于private _data: Model | undefined
,可以简写为private _data?: Model
。
是的,在这个 sn-p 中 typeof
是不必要的,我提到它是为了确保读者在适应其他代码时知道原始类型。我同意缩短未定义检查,并将编辑帖子以适应它。虽然我会在我写的时候留下_data
声明,主要是因为它更清楚地表明它最初是undefined
。虽然我通常在代码中使用可选参数,但我更喜欢更长、更明确的形式,在这个平台上编写代码时更容易掌握——让初学者更容易理解。谢谢!以上是关于vue-class-component:如何创建和初始化反射数据的主要内容,如果未能解决你的问题,请参考以下文章
vue-class-component + typescript:如何在导入的函数中使用组件的类作为“this”的类型?
如何在 vue-class-component 中使用动态组件
如何通过 vue-class-component 使用 Vue Router 延迟加载?
vue-class-component 语法中 vue-models(因此,“props”)的计算 getter/setter