Vue组件道具更改不会触发重新渲染

时间:2018-05-03 16:11:51

标签: vuejs2 vue-component

在我的Vue 2应用程序中,我有一个大对象,它从根组件向下传递到几个级别,作为prop。当我更改对象的某些属性时,子组件应该更新并重新呈现。在某些情况下,他们会这样做,在其他情况下他们不会。我需要一些帮助来发现它为什么不起作用。

这是一个子组件,它不会更新:

<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确实已更改,但我需要关闭并重新打开该组件以查看更改。此外,浏览器开发工具不会立即显示更改。我需要单击组件来刷新调试器中的值。

编辑: entity类基本上看起来像这样(摘录):

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

我进行了更深入的搜索,似乎可以归结为:对象的某些属性是被动的(它们具有由vue创建的getter / setter)而有些属性并不是。 entity.name有一个setter,因此更改它会更新组件。 entity.level没有。这里有一个问题:他们为什么被区别对待?这是一个日志:

console.log of entity

2 个答案:

答案 0 :(得分:2)

如果没有看到entity.levelUp的代码,就无法确定,但这似乎是一个反应性问题,可以通过在该函数中使用Vue.$set来解决。

您可以在this.$forceUpdate();

之后添加this.entity.levelUp();来确认这种情况

<强>更新

this._level = this._level + 1;

可以更改为

Vue.$set(this, _level, this._level + 1); 您需要在该组件/文件中导入Vue以访问$ set函数

答案 1 :(得分:2)

您没有显示(或找不到)更改对象的代码,但是您使用$set()Vue.set()而不是直接更改对象的属性?由于reactivity limitations

,通常直接更改属性不起作用

编辑添加:

我现在看到了。我想你想要的东西:

this.$set(this, '_level', this._level + 1);
相关问题