Apollo Client请求成功但结果undefined,无法访问数据求助
问题分析与解决方案
核心问题
你在Vuex Action中直接使用useQuery是错误的——useQuery是Vue Apollo的Composition API钩子,必须在组件的setup()函数或<script setup>上下文里调用,Vuex Action不属于这个上下文,因此result无法正确获取查询数据,最终导致提交到Store的内容是undefined,组件访问时触发报错。
具体修复步骤
1. 修改Vuex Action:使用Apollo Client的client.query方法
将useQuery替换为Promise-based的client.query,这是适合在异步Action中执行GraphQL查询的正确方式:
async questionSearch({ commit }, data) { const ALL_QUESTION_SEARCH = gql` query searchQuestion( $token: String $bookId: String! $page: Int $keyword: String $field: String $source: String $fromYear: Int $toYear: Int $topic: String $minDifficultyLevelId: Int $maxDifficultyLevelId: Int $starred: Boolean ) { searchQuestion( args: { token: $token bookId: $bookId page: $page keyword: $keyword field: $field source: $source fromYear: $fromYear toYear: $toYear topic: $topic minDifficultyLevelId: $minDifficultyLevelId maxDifficultyLevelId: $maxDifficultyLevelId starred: $starred } ) { question { information { bookId topic isRoot childCount parentId } stats { like difficultyLevelId } source { name publishYear field } content { question type answers { id text isTrue } } key { description } rowNumber sortingInformation { season section subSection index } starred id isAnswered answers { bookId questionId answerId isTrue timestamp userId } } } } ` try { // 调用Apollo Client的query方法,await获取结果 const response = await this.$apollo.query({ query: ALL_QUESTION_SEARCH, variables: { bookId: data.bookId, page: data.page, keyword: data.keyword, field: data.field, source: data.source, fromYear: data.fromYear, toYear: data.toYear, topic: data.topic, minDifficultyLevelId: data.minDifficultyLevelId, maxDifficultyLevelId: data.maxDifficultyLevelId, starred: data.starred, token: localStorage.getItem('token'), } }) // 提取查询结果中的有效数据 const questionsData = response.data.searchQuestion commit('questions', questionsData) commit('setSuccess', null) // 成功时将错误状态设为null } catch (error) { commit('setSuccess', error) console.error('查询失败:', error) } }
2. 调整组件调用逻辑:增加空值判断
确保在访问数据前先检查Store中的数据是否存在,避免触发undefined报错:
async searchQuestions() { let form = { bookId: this.id, page: this.page || '', keyword: this.keyword || '', field: this.field || '', source: this.source || '', fromYear: this.fromYear || 1364, toYear: this.toYear || 1402, topic: this.book_topic || '', minDifficultyLevelId: this.minDifficultyLevelId || 0, maxDifficultyLevelId: this.maxDifficultyLevelId || 40, difficultyLevel: this.difficultyLevel || 40, starred: this.starred || false, } await this.questionSearch(form) // 先判断数据是否存在,再赋值 if (this.getQuestions?.question) { this.questionList = this.getQuestions.question } else { this.questionList = [] // 无数据时设为空数组,避免模板报错 } }
3. 模板渲染:增加条件判断
在模板中展示数据时,通过v-if确保数据加载完成后再渲染:
<template> <div v-if="questionList.length"> <!-- 遍历展示questionList内容 --> <div v-for="item in questionList" :key="item.id"> <!-- 具体内容渲染 --> </div> </div> <div v-else> 暂无数据 </div> </template>
关键注意点
useQuery是Composition API专属钩子,只能在组件的Composition上下文(如setup()、<script setup>)中使用,不能在Vuex Action、普通函数中直接调用。- 使用
client.query返回Promise,适合在异步Action中通过await获取结果,能正确拿到GraphQL查询返回的data。 - 始终在访问嵌套属性前做空值判断(如使用可选链操作符
?.),避免因数据未加载完成导致的报错。
内容的提问来源于stack exchange,提问作者sanaz baghban
相关产品推荐
相关产品推荐

