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

Vue监听prop变化调用useLazyQuery触发onServerPrefetch报错如何解决?

错误根因

这个报错的核心原因是useLazyQuery属于Vue组合式API封装的Apollo钩子,必须在setup函数的同步执行阶段直接调用,不能嵌套在异步函数、watch回调等非setup同步上下文中执行,否则会丢失组件实例关联,导致生命周期钩子注入失败。
另外你对useLazyQuery的用法也有问题:它本身不是异步方法,不需要await,调用后会返回一个手动触发查询的load方法,以及你需要的响应式状态result、error、loading。


修正方案

方案1:使用useLazyQuery手动触发查询

<script lang="ts">
import { ref, defineComponent, watch } from "vue";
import gql from "graphql-tag";
import { useLazyQuery, useResult } from "@vue/apollo-composable";

export default defineComponent({
  props: {
    message: [String],
  },

  setup(props) {
    const pageNumber = ref<number>(1);

    // 直接在setup顶层同步调用useLazyQuery
    const { load, result, error, loading } = useLazyQuery(
      gql`
        query getCharacters($page: Int!, $name: String!) {
          characters(page: $page, filter: { name: $name }) {
            info {
              count
              pages
            }
            results {
              id
              name
              image
              gender
              species
              episode {
                episode
              }
            }
          }
          location(id: 1) {
            id
          }
          episodesByIds(ids: [1, 2]) {
            id
          }
        }
      `,
      // variables设为响应式函数,每次触发查询都会自动取最新值
      () => ({
        page: pageNumber.value,
        name: props.message,
      })
    );

    // 直接用useResult解析响应数据,本身是响应式的
    const characters = useResult(result, [], (res) => res.characters.results);

    // 监听prop变化,调用load手动触发查询
    watch(() => props.message, () => {
      if (props.message) load();
    }, { immediate: true }); // immediate设为true则组件初始化就触发第一次查询

    // 把需要的状态返回给模板使用
    return {
      characters,
      loading,
      error,
      pageNumber
    };
  },
});
</script>

方案2:使用useQuery自动触发查询(更推荐)

如果不需要手动控制查询触发时机,直接用useQuery即可,它会自动监听响应式variables的变化自动重查,不需要额外写watch:

const { result, error, loading } = useQuery(
  gql`/* 同上的查询语句 */`,
  () => ({
    page: pageNumber.value,
    name: props.message,
  }),
  {
    // 配置查询触发条件,比如message为空时不查询
    enabled: () => !!props.message
  }
)
const characters = useResult(result, [], (res) => res.characters.results);

内容的提问来源于stack exchange,提问作者Krzysztof

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:18:03