【问题标题】:VueJS reactivity issue for object inside array数组内对象的VueJS反应性问题
【发布时间】:2019-11-09 14:20:38
【问题描述】:

我已将我的数据对象声明为queuedItemList: [],它应该包含由后台服务提供的一组项目。在 HTTP 请求之后,我使用类似的 for 循环填充列表

for(var i = 0; i < getList.length; i++) {
    var newObject = Object.assign({}, getList[i]);
    this.queuedItemList.splice(i, 1, newObject);
}

用于填充以下模板

<Item v-for="(item, index) in queuedItemList" :key="index" :componentData="item" :index="index" @remove="removeItem">
</Item>

我应该定期执行 HTTP GET 来获取新的项目列表,其中还可能包含状态可能不同的当前项目。在组件内部,我使用v-if 在两个不同的图标之间进行选择。

<v-icon name="play" class="controlIcons" v-if ="playControl" />
<v-icon name="pause" class="controlIcons" v-if ="!playControl" />

现在,在一些 HTTP 请求之后,我在 Vue Devtools 中看到 playControl 的值发生了变化,这证实了实际值反映在组件中。但是,由于playControl 值的变化,我看不到图标的变化。此外,如果我刷新屏幕,一切都会按预期工作。

我的猜测是我在某处搞砸了反应性。谢谢!

【问题讨论】:

    标签: vue.js vuejs2 vue-component vuetify.js


    【解决方案1】:

    您正在寻找https://vuejs.org/v2/guide/reactivity.html

    for(var i = 0; i < getList.length; i++) {
        var newObject = Object.assign({}, getList[i]);
        this.$set(this.queuedItemList, i, newObject);
    }
    

    另一种方法可能是更新父项的项目列表 :key - 因此,每次添加项目时都会重新渲染它:

    </div :key="computedKey">    
        <Item v-for="(item, index) in queuedItemList" :key="index" :componentData="item" :index="index" @remove="removeItem"></Item>
    </div>
    

    computed: {
        computedKey () {
            return this.queuedItemList.length
        }
    }
    

    【讨论】:

    • 在数组长度不变的情况下,key方法会起作用吗?
    • 出于某种原因,这对我不起作用。我需要在某处添加观察者吗?
    • 长度需要改变,但是 this.$set 应该可以解决问题:o
    • 它成功了,只是我在另一端的观察者有点坏了。谢谢!
    【解决方案2】:

    我不知道“playcontrol”的结构

    <v-icon name="play" class="controlIcons" v-if ="playControl" />
    

    我过去通过类似的东西,当你更新“playControl”值时,你只是“playControl = newValue”?如果这样做,这可能会破坏反应性,请尝试使用 Vue $set 指令,例如:

    Vue.set(this.playControl, <value>);
    

    https://vuejs.org/v2/guide/migration.html#vm-set-changed

    【讨论】:

    • playControl 只是一个布尔变量,在创建过程中像this.playControl = ['NotStarted', 'Stopped', 'Paused'].includes(this.componentData.State); 一样分配。我不确定这是否可行,但我仍然会尝试一下。
    • 我试过了,我得到了"TypeError: right-hand side of 'in' should be an object, got boolean"
    • hmmmm,好的,一旦我需要强制组件刷新代码,Vue 提供,"this.$forceUpdate()" 在获取新的项目列表后尝试; br.vuejs.org/v2/api/index.html#vm-forceUpdate
    【解决方案3】:

    原来我需要的是 setter 和 watchers 的组合。我在组件级别使用了@alx.lzt 的 setter 和 watcher,解决了所有问题

    【讨论】:

      【解决方案4】:

      您可以使用多个属性进行反应性检查,$set 更改对象中的属性,$nextTick 分配值。

      如果两者都不起作用,您可以尝试$forceUpdate()

      【讨论】:

        猜你喜欢
        • 2017-11-09
        • 2020-05-17
        • 2021-03-08
        • 1970-01-01
        • 2016-03-31
        • 2019-04-02
        • 2016-05-17
        • 2023-03-22
        • 2020-10-23
        相关资源
        最近更新 更多