Vue3 Apollo4无法访问useQuery结果_rawValue的ReferenceError问题
问题分析与解决方案
核心问题是useQuery返回的result是异步更新的Ref对象,初始状态下result.value为空,直接访问result.allBlogs会因为数据尚未加载完成而报错或无法获取值。
一、组件内数据处理修复
组件中blogs计算属性直接访问result.allBlogs,但初始时result.value可能未包含allBlogs,需要添加空值判断:
<template> <v-container> <v-row> <!-- 现在可以正常显示 --> {{ blogs }} </v-row> <v-row> {{ result.allBlogs?.map(item => item.name) }} </v-row> </v-container> </template> <script setup> import { useQuery } from '@vue/apollo-composable' import { computed } from "vue" import { ALL_BLOGS } from "@/queries" const { result } = useQuery(ALL_BLOGS); // 添加可选链操作符,避免初始时未加载完成导致的报错 const blogs = computed(() => result.value?.allBlogs?.map(item => item.name) || []); </script>
解释:
- 使用
result.value访问Ref的原始值(组合式API中Ref需要通过.value访问,模板中会自动解包) - 用
?.可选链操作符,防止allBlogs未定义时触发报错 - 最后加
|| []确保初始状态下blogs是一个空数组,避免模板显示undefined
二、Pinia仓库中数据处理修复
Pinia的action中使用useQuery时,需要监听result的变化来处理数据,推荐两种方式:
方式1:使用watch监听result变化
import { defineStore } from "pinia" import { useQuery } from '@vue/apollo-composable' import { watch } from 'vue' import { ALL_BLOGS } from "@/queries"; export const useBlogStore = defineStore({ id: "BlogStore", state: () => ({ blog_api: [], }), actions: { getAllBlogs() { const { result } = useQuery(ALL_BLOGS) // 监听result的变化,当数据加载完成后处理 watch(result, (newValue) => { if (newValue?.allBlogs) { this.blog_api = newValue.allBlogs.map(item => item.name) } }, { immediate: true }) // immediate: true 确保初始时也会执行一次 }, }, });
方式2:使用onResult回调(Apollo官方推荐)
useQuery返回的onResult方法可以直接处理请求完成后的结果:
import { defineStore } from "pinia" import { useQuery } from '@vue/apollo-composable' import { ALL_BLOGS } from "@/queries"; export const useBlogStore = defineStore({ id: "BlogStore", state: () => ({ blog_api: [], }), actions: { getAllBlogs() { const { onResult } = useQuery(ALL_BLOGS) // 请求完成后触发回调 onResult(({ data }) => { if (data?.allBlogs) { this.blog_api = data.allBlogs.map(item => item.name) } }) }, }, });
解释:
onResult会在请求成功返回数据时触发,直接拿到data对象,无需手动处理Ref的value- 添加空值判断确保数据存在时再处理,避免报错
关键注意点
- 组合式API中,Ref对象必须通过
.value访问原始值(模板中会自动解包,所以模板里可以直接写result.allBlogs) useQuery是异步请求,必须等待数据返回后再处理,不能同步直接访问结果- 可选链
?.和空值合并||是处理异步数据初始状态的常用手段,避免页面报错
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

