Vue中传递数组参数仅获Observer,如何改用数组实际数据?
问题分析与解决方案
我一眼就看出问题所在啦——你踩了异步操作的典型坑!核心问题是请求数据的时机和计算总时长的时机不匹配,再加上Vue响应式系统对数组的包装,才导致你拿到Observer对象且没法用真实数组数据。
为什么会出现这个情况?
this.$http().get(url)是异步操作,它不会等请求完成再执行后续代码:
- 你发起请求后立刻调用了
getTotalHours(this.reportingsList),这时候请求还没拿到后端数据,reportingsList还是初始的空数组[],而Vue会把响应式数组包装成Observer对象(这是响应式系统的正常表现,不用慌)。 - 等请求成功后,
then回调里的this.reportingsList = response.data才会执行,但这时候getTotalHours早就跑完了,根本没用到新数据。
修复方案
1. 调整方法调用时机(最直接的修复)
把getTotalHours移到then回调内部,确保只有当数据真正赋值给reportingsList之后再执行:
getAll() { const url = 'reportings/getAll'; this.$http().get(url).then((response) => { this.reportingsList = response.data; console.log(this.reportingsList.length); // 现在这里能拿到正确的长度了 this.getTotalHours(this.reportingsList); // 把调用移到这里! }); // 删除原来这里的getTotalHours调用 }
2. (推荐)用计算属性优化总时长计算
既然totalHours是依赖reportingsList的衍生数据,用Vue的计算属性会更贴合响应式设计,不用手动调用方法更新:
// 先把data里的totalHours删掉,然后添加computed选项 computed: { totalHours() { // 用reduce更简洁地计算总和 return this.reportingsList.reduce((sum, item) => sum + item.hours, 0); } }
这样只要reportingsList更新,totalHours会自动重新计算,你甚至可以删掉getTotalHours方法,代码更清爽。
关于Observer对象的小说明
Vue会把data里的响应式数据(数组、对象)包装成Observer实例,这是响应式系统的正常工作机制。你完全可以像操作普通数组一样使用this.reportingsList——比如用length、forEach、map这些方法,Vue会自动处理响应式更新,不需要特意“解包”。
内容的提问来源于stack exchange,提问作者Igor Formiga
相关产品推荐
相关产品推荐

