Vue3+Apollo+GraphQL访问menu.menuItems.nodes报undefined错误
问题原因
报错是组件初始渲染阶段的时序问题+配置错误共同导致的:
- Apollo查询是异步发起的,组件第一次渲染时接口数据还未返回,此时
menu取的是你在data里定义的初始值空数组[],空数组上不存在menuItems属性,menu.menuItems为undefined,继续读取undefined的nodes属性就会触发类型错误 - 你将
loading初始值设为数字0(falsy值),Apollo返回的加载状态是布尔值,类型不匹配导致初次渲染时不会走加载态分支,直接执行深层属性的取值逻辑,放大了异常 menu初始值设为数组,但接口实际返回的menu是对象类型,初始值结构和实际返回不匹配,没有提前声明深层属性的默认值
直接访问menu.menuItems不报错的原因是:Vue模板渲染undefined/null类型值时不会抛出异常,只会渲染为空;但尝试从undefined/null上读取子属性时会直接触发类型错误。
修复方案
按以下步骤调整即可解决问题:
- 修正
data里的初始值,和接口返回结构对齐,同时修正loading类型
data() { return { menu: { menuItems: { nodes: [] } }, loading: true, }; },
- 给Apollo查询增加
update配置,明确指定要挂载到menu变量上的字段,避免层级解析错误
apollo: { menu: { query: MENU_QUERY, update(response) { return response.menu; } }, },
- 模板中保留加载态判断,确保数据返回后再渲染深层属性
<template> <div> MENU LIST <h4 v-if="loading">Loading...</h4> <div v-else> {{ menu.menuItems.nodes }} <!-- 后续遍历菜单项可直接在此处写v-for逻辑 --> </div> </div> </template>
如果不想调整初始值,也可以直接在模板里用可选链做防御性访问,写法更简洁:
{{ menu?.menuItems?.nodes }}
内容的提问来源于stack exchange,提问作者Franky
相关产品推荐
相关产品推荐

