Vue中computed属性无法读取created初始化数据的问题咨询
问题分析与解决方案
这个问题我碰到过好多次,核心其实是异步请求的时序问题加上你可能忽略了data初始值的设置,先给你理清楚来龙去脉:
先搞清楚执行时机
首先纠正一个误区:computed属性不是在created之前执行,它是惰性求值的——只有当它被依赖(比如模板里用到它,或者其他代码引用它)的时候,才会触发计算。
Vue实例的初始化顺序大概是:
- 初始化props
- 初始化data(这时候你的
info是你设置的初始值) - 初始化computed(只是注册,还没计算)
- 调用created钩子(你在这里发起异步请求)
但关键点来了:getSomething()是异步请求,它发送出去之后不会等着返回结果,而是直接继续执行后续代码。所以created钩子执行完的时候,请求还在服务器路上,this.info还是你最开始在data里设置的初始值(大概率是undefined或者null,不是数组)。这时候如果你的computed属性被模板引用了,Vue就会立刻去计算它,对undefined调用forEach自然就报错了。
等后续请求返回,this.info被更新成数组的时候,computed会因为依赖的info发生变化,自动重新计算一次,这时候就能正常执行forEach了——但首次计算时的报错已经发生了。
解决方法(两步走)
1. 给info设置正确的初始值
这是最直接的解决方式,在data里把info初始化为空数组:
data() { return { info: [] // 初始化为空数组,而不是undefined/null } }
这样即使请求还没返回,this.info是个空数组,调用forEach不会报错(只是循环体不会执行而已),等请求返回更新info后,computed会自动重新计算,拿到正确的结果。
2. 在computed里加防御性检查(可选但推荐)
为了避免后续可能的异常(比如请求返回的不是数组),可以在computed里先做判断:
computed: { processedInfo() { // 先确认info是数组,不是的话返回默认值 if (!Array.isArray(this.info)) { return [] } // 再执行你的forEach逻辑 const processed = [] this.info.forEach(item => { // 你的处理代码,比如提取某个属性 processed.push(item.name) }) return processed } }
这样不管info是什么状态,都不会出现forEach is not a function的错误了。
内容的提问来源于stack exchange,提问作者hidar
相关产品推荐
相关产品推荐

