在 vue.js 中更改复杂的计算对象
Posted
技术标签:
【中文标题】在 vue.js 中更改复杂的计算对象【英文标题】:Changing complex computed object in vue.js 【发布时间】:2018-04-25 20:44:42 【问题描述】:我有一张桌子的复杂对象。看起来像这样:
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 个小时进行重构和尝试。 提前致谢 解决方案 就我而言,可以有两种状态:有活动,没有活动。所以我为每种情况制作了两个计算道具并分别渲染它们并通过 v-if="activities.length"
进行切换【问题讨论】:
仅从您发布的代码中很难了解全局,但我之前使用过日期和计算属性,Vue 不会将Date
更改为更新。计算的属性被缓存,并且只有在它们的依赖项更新时才会更新,所以这可能是你的 hour-td
组件不工作的原因。我要尝试的第一件事是根据计算属性中的时间戳创建一个new Date()
。
是的,你说得对缓存。但问题不是日期(它总是在时间戳中,所以我像处理数字一样工作,它们也来自服务器)而不是缓存(我使用观察者,重写缓存)。在这里你可以找到组件的完整代码github.com/Vasek18/my-hours.ru/blob/master/resources/assets/js/…
【参考方案1】:
我认为您的问题是与数组直接分配的 Change Detection Caveats
(您可以阅读 here)的 Vue 已知问题有关,它不会检测到更改。
您应该更改这部分代码(使用直接数组赋值):
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,但没有成功
你的意思是:“没有成功”?可以分享一下代码吗?我有同样的问题,我用 Vue.set 解决了..
您也可以查看vm.$forceUpdate()
,尝试在最后一个console.log 之后执行或获取vm.$nextTick( [callback] )
中的所有代码以执行所有操作(加载表中的数据)然后,在下一个刻度上重新渲染组件。
更多信息在这里:https://vuejs.org/v2/api/#vm-forceUpdate && 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);
希望对你有帮助!
【讨论】:
感谢您的回复,但我仍然无法解决这个问题。所以我尝试了“Vue.set(vm.tds[dateTimestamp].hours[activity.start_at].activity, 'activity', activity.activity);”和“Vue.set(vm.tds, dateTimestamp, vm.tds[dateTimestamp]);”和“让 temp = activity.start_at; Vue.set(vm.tds[dateTimestamp].hours, activity.start_at, key: activity: activity);”在循环中。没有结果。也可以试试“this.$children.forEach(function(child) child.$forceUpdate(); );”。也没有成功 感谢您的帮助。这种方法行不通,因为它不是数组,而是对象,而且,我的理解是,vue 无法在对象中的对象中做出反应性的对象。所以我有另一个解决方案。活动存在的情况下的两个单独的道具。你可以在这里看到它github.com/Vasek18/my-hours.ru/blob/master/resources/assets/js/… 好的!我很高兴你找到了解决方案。尝试编辑并回答您自己的问题,以帮助将来遇到同样问题的人!如果答案有帮助,请点赞;)以上是关于在 vue.js 中更改复杂的计算对象的主要内容,如果未能解决你的问题,请参考以下文章