Vue3 v-for渲染Apollo列表报渲染函数执行未处理错误警告
警告产生原因
@vue/apollo-composable的useQuery发起的GraphQL请求是异步执行的,组件首次渲染时请求还未返回,此时返回的result响应式变量还未被注入查询结果,直接在模板中访问result.clients相当于读取undefined上的属性,触发JS运行时错误。Vue在渲染函数执行、调度器刷新两个阶段捕获到这个未处理的错误,就会抛出你看到的两条警告。
等请求完成后result被赋值为返回数据,列表可以正常渲染,但首次渲染阶段抛出的错误不会消失,所以就出现了「功能正常但控制台有警告」的现象。注释v-for代码后没有了对未初始化属性的访问,警告自然消失。
修复方案
以下方案任选其一即可,推荐优先用第一种或第二种,代码更简洁:
- 方案1:给循环目标加可选链和空值兜底,避免读取undefined属性
直接修改模板中v-for绑定的遍历目标,当result未初始化时自动遍历空数组,不会触发属性读取错误:<p v-for="c in result?.clients ?? []" :key="c.id"> <b>{{ c.id}}</b> </p> - 方案2:结合加载状态做条件渲染
从useQuery的返回值中解构出loading状态,等数据加载完成后再渲染列表区域,逻辑更清晰,还可以自定义加载提示:
首先修改script部分:
再修改模板部分:import { getClients } from "@/graphql/query.js" import { useQuery } from '@vue/apollo-composable' export default { name: 'clients_list', setup(){ // 解构出loading状态 const { result, loading } = useQuery(getClients); return { result, loading } }, }<!-- 可选:自定义加载中提示 --> <div v-if="loading">列表加载中...</div> <p v-else v-for="c in result.clients" :key="c.id"> <b>{{ c.id}}</b> </p> - 方案3:给查询设置初始值
调用useQuery时传入初始值配置,让组件首次渲染时result就带有clients空数组属性,从根源避免属性读取错误:
设置后模板不需要额外修改,原有v-for写法可以直接保留。const { result } = useQuery(getClients, null, { initialValue: { clients: [] } });
注意:如果你核对接口返回后发现
clients实际挂载在result.data下,把上述代码中所有result.clients替换为result.data.clients即可,当前你描述数据可以正常展示,说明apollo已经自动做了data层的拆包,不需要额外调整路径。
内容的提问来源于stack exchange,提问作者ccsv
相关产品推荐
相关产品推荐

