在vue.js中更改复杂的计算对象

时间:2017-11-13 08:17:30

标签: vue.js vuejs2 javascript-objects vue-component computed-properties


我有一个复杂的表格对象。看起来像这样:

{
    1510002000: {
        date: "07.11.17"
        hours: {
            1510002000:{
                activity:{
                    activity: "Тест",
                    color: "#00ff00",
                    end_at: 1510005600,
                    start_at: 1510002000,
                    type_id: 1
                }
            },
            1510005600: {
                ...
            },
            ...
        }
    },
    ....
}

这是使用此对象的模板中的代码:

    <tr v-for="date in this.tds">
        <td>{{ date.date }}</td>
        <td is="hour-td"
            v-for="hour in date.hours"
            :color="hour.activity.color"
            :start_at="hour.activity.start_at"
            :end_at="hour.activity.end_at"
            :activity="hour.activity.activity"
            :type_id="hour.activity.type_id"
        >
        </td>
    </tr>

我将它评估为计算属性,但是当父组件提供数据同步时我需要重新渲染表,所以我有一个prop的观察者(prop称为“活动”):

watch: {
    activities: function(){
        var vm  = this;
        let dth = new DateTimeHelper;

        if (this.activities.length > 0){
            this.activities.forEach(function(activity){
                let dateTimestamp = dth.getDateTimestampFromTimestamp(activity.start_at); // just getting the key

                if (vm.tds[dateTimestamp]){
                    if (vm.tds[dateTimestamp].hours[activity.start_at]){
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.activity = activity.activity;
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.color    = activity.color;
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.type_id  = activity.type_id;
                    }
                }
            });
        }

        console.log(vm.tds) // here I can see that the object is filled with new data
    }
},

问题是该表不会重新呈现。更准确地说,组件“hour-td”不包含新数据 我也试过使用Vue.set,但没有成功
你能帮我更新一下表吗?我花了5个小时进行重构和尝试 提前致谢

SOLUTION
在我的情况下,可以有两种状态:有活动,没有活动。所以我为每个案例制作了两个计算道具并分别渲染它们并通过v-if =“activities.length”

进行切换

1 个答案:

答案 0 :(得分:0)

我认为您的问题在于Change Detection Caveats的Vue已知问题(您可以阅读here)数组直接分配,但不会检测到更改。

您应该更改此部分代码(使用直接数组分配):

if (vm.tds[dateTimestamp]){
   if (vm.tds[dateTimestamp].hours[activity.start_at]){
      vm.tds[dateTimestamp].hours[activity.start_at].activity.activity = activity.activity;
      vm.tds[dateTimestamp].hours[activity.start_at].activity.color    = activity.color;
      vm.tds[dateTimestamp].hours[activity.start_at].activity.type_id  = activity.type_id;
   }
}

使用数组的Vue.set()选项以检测更改并重新呈现组件。它在不同的场合对我有用:

// Vue.set(object, key, value)
// something like this: 
Vue.set(vm.tds[dateTimestamp].hours[activity.start_at].activity.activity,1,activity.activity);

此处有更多信息:https://codingexplained.com/coding/front-end/vue-js/array-change-detection

编辑:

我现在看到你说:

  

此外,我还尝试过使用Vue.set,但

没有成功

你的意思是:&#34;没有成功&#34; ?你能分享一下代码吗?我有同样的问题,我解决了Vue.set ..

您还可以查看vm.$forceUpdate(),尝试在最后一个console.log之后执行或者获取vm.$nextTick( [callback] )中的所有代码以执行所有操作(在表中加载数据)然后,在下一个刻度上重新渲染组件。

此处有更多信息:https://vuejs.org/v2/api/#vm-forceUpdate&amp;&amp; https://vuejs.org/v2/api/#Vue-nextTick

编辑2:

我认为你的问题在于数组的索引,你应该看看这里:https://vuejs.org/v2/guide/list.html#Array-Change-Detection。 尝试更改:

if (vm.tds[dateTimestamp]){
                    if (vm.tds[dateTimestamp].hours[activity.start_at]){
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.activity = activity.activity;
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.color    = activity.color;
                        vm.tds[dateTimestamp].hours[activity.start_at].activity.type_id  = activity.type_id;
                    }
                }

并简化:

if (vm.tds[dateTimestamp] && vm.tds[dateTimestamp].hours[activity.start_at]){
   Vue.set( vm.tds, vm.tds.indexOf(vm.tds[dateTimestamp].hours[activity.start_at]), activity);
}

希望它有所帮助!