You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:40:38