Vue3 Composition API异步加载JSON访问数组嵌套属性报错求解
问题根因
核心问题是异步请求的时序问题 + 模板表达式的容错逻辑差异:
- 你初始化响应式变量时给
people的默认值是空对象{},而fetch是异步网络请求,组件第一次执行渲染的时候,请求还没返回结果,此时people.value就是初始的空对象,不存在People属性。 - 你提到的几个“正常运行”的写法,本质都是没有在首次渲染时触发非法属性访问:
{{ people }}:直接渲染变量本身,不管是初始空对象还是后续赋值的JSON数据,都不会访问深层不存在的属性,自然不报错{{ people.People }}:访问空对象的People属性只会得到undefined,模板渲染undefined时会自动转成空文本,不会继续向下访问属性,所以不报错v-for="(item, idx) in people.People":Vue框架对v-for指令做了内置容错,如果遍历的目标值是undefined/null,会直接按空数组处理,不会抛出错误,等后续数据加载完成会自动触发重新遍历渲染
- 报错的
{{ people.People[0].FullName }}逻辑不一样:首次渲染时people.People是undefined,代码直接尝试对undefined按下标取[0],这是JS原生的类型错误,会直接抛出TypeError,等不到后续请求返回赋值就已经中断渲染了。
修复方案
任选一种即可解决问题:
- 方案1:给响应式变量设置匹配数据结构的初始默认值
把初始化代码从const people = ref({});改成:
这样首次渲染时const people = ref({ People: [] });people.People是空数组,访问[0]得到undefined,模板会自动渲染为空文本,等数据加载完成后就会自动显示正确内容,不会抛错。 - 方案2:用可选链操作符做安全访问
把报错行的模板表达式改成可选链写法:
可选链会在左侧值为<p>{{ people.People?.[0]?.FullName }}</p>undefined/null时直接短路返回undefined,不会继续向下访问属性,从根源避免非法访问报错。 - 方案3:加渲染判断,等数据就绪后再渲染对应节点
给报错的标签加v-if判断,只有当People数组存在且有数据时才渲染节点:
首次渲染阶段这个节点不会被创建,自然不会触发属性访问错误。<p v-if="people.People?.length">{{ people.People[0].FullName }}</p>
内容的提问来源于stack exchange,提问作者Oscar H. Preis
相关产品推荐
相关产品推荐

