Изменение реквизита компонента Vue не вызывает повторного рендеринга - PullRequest
0 голосов
/ 03 мая 2018

В моем приложении Vue 2 у меня есть большой объект, который передается от корневого компонента на несколько уровней к некоторым дочерним компонентам в качестве реквизита. Когда я изменяю некоторые свойства объекта, дочерние компоненты должны обновляться и перерисовываться. В некоторых случаях они делают, в других случаях они не делают. Мне нужна помощь, чтобы определить, почему это не работает.

Вот дочерний компонент, который не обновляется:

<template>
<div class="upgradeBar">
    {{level}}
    <div
            v-for="lvlNum in maxLevel + 1"
            class="level"
            v-bind:class="{reached: isLevelReached(lvlNum - 1)}"
    ></div>

    <button
            class="btnUpgrade"
            @click="onLevelUp()"
            v-if="!isLevelReached(maxLevel)"
    >
        +
    </button>
</div>
</template>


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

@Component()
export default class UpgradeBar extends Vue {
    name: 'UpgradeBar';

    @Prop() entity: Upgradable;

    get level(): number {
        return this.entity.level;
    }

    get maxLevel(): number {
        return this.entity.MAX_LEVEL;
    }

    onLevelUp() {
        this.entity.levelUp();
    }

    isLevelReached(level: number): Boolean {
        return this.entity.level >= level;
    }
}
</script>

Компонент называется так:

<UpgradeBar :entity="entity" />

Весь код работает. Когда я нажимаю кнопку btnUpgrade entity.level действительно изменяется, но мне нужно закрыть и снова открыть компонент, чтобы увидеть изменения. Кроме того, инструмент разработки браузера не показывает изменения мгновенно. Мне нужно нажать на компонент, чтобы обновить значения в отладчике.

EDIT: Класс entity выглядит примерно так (отрывок):

class Entity {
    name: string = 'some name';
    level: number = 1;
}

Я искал глубже, и, похоже, все сводится к следующему: некоторые свойства объекта являются реактивными (у них есть методы получения / установки, созданные с помощью vue), а некоторые - нет. entity.name имеет установщик, поэтому при его изменении обновляется компонент. entity.level нет. Вот вопрос: почему к ним относятся по-разному? Вот журнал:

console.log of entity

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Вы не показываете (или я не могу найти) код, который изменяет объект, но вы используете $set() или Vue.set() вместо простого изменения свойств объекта напрямую? Прямое изменение свойства обычно не работает из-за ограничений реактивности


Отредактировано, чтобы добавить:

Теперь я вижу. Я думаю, что вы хотите что-то вроде:

this.$set(this, '_level', this._level + 1);
0 голосов
/ 03 мая 2018

Не могу сказать наверняка, не увидев код для entity.levelUp, но это похоже на проблему реактивности, которую можно решить, используя Vue.$set внутри этой функции.

Вы можете подтвердить это, добавив this.$forceUpdate(); после this.entity.levelUp();

обновление

this._level = this._level + 1;

можно изменить на

Vue.$set(this, _level, this._level + 1); Вам нужно будет импортировать Vue в этот компонент / файл для доступа к функции $ set

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...