vue-class-component: как создавать и инициализировать отражающие данные - PullRequest
2 голосов
/ 16 апреля 2019

Я использую vuejs с машинописью и 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>

В этой первой версии я получил эту ошибку:

Свойство или метод "data" не определены в экземпляре, но на них ссылаются во время рендеринга

Это нормально, как сказано на странице компонента vue-class, неопределенные данные не будут отражающими.Мне нужно инициализировать данные на ноль.Кроме того, я получаю эту ошибку машинописного текста:

Свойство 'data' не имеет инициализатора и не определено в конструкторе

Поэтому я хочу сделать это:

private data: Model = null;

Но я получаю эту ошибку машинописи:

Тип 'null' нельзя назначить типу 'Model'.

Я не хочуне нужно менять тип данных на Model | null, потому что мне придется проверять, везде ли данные равны нулю, я буду их использовать, и я знаю, что данные никогда не будут равны нулю.

private data!: Model;

Также не работаетпотому что данные будут неопределенными и поэтому не будут реагировать.

Я не хочу отключать проверки машинописи, потому что они полезны для других частей кода.

Есть ли правильный способинициализировать данные здесь?

Ответы [ 2 ]

3 голосов
/ 26 июня 2019

Правильный тип для такого свойства:

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 легче обрабатывать в TypeScript, чем null, особенно потому, что это позволит пометить свойство как необязательное.

Я знаю, что данные никогда не будут нулевыми.

Это будет nullпока компонент не смонтирован, остается место для ошибки:

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

public mounted() {
    this.data = {...this.$store.getters.data};
}
1 голос
/ 26 июня 2019

Вы можете использовать метод получения вместо непосредственного назначения данных, предполагая, что данные устанавливаются в хранилище при его создании.Убедитесь, что ваши получатели магазина безопасны для типов!

@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;
...