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

Vite热加载表现不一致:Vue3+TS项目Urql查询首次加载无返回仅热更后正常

问题根因与解决方案

你遇到的是Urql查询返回结果的响应性丢失问题,按以下优先级排查即可解决:

1. 避免直接解构useQuery返回的响应式对象

Urql的useQuery返回的是浅层响应式对象,直接解构会丢失响应性触发能力:
错误写法:

const { data, fetching } = useQuery({ query: QUERY })
// 后续data更新不会触发响应

正确写法二选一:

  • 始终通过返回的result对象访问属性:
    const result = useQuery({ query: QUERY })
    // 访问时用 result.data.value、result.fetching.value
    
  • 用toRef包裹需要解构的属性保留响应性:
    import { toRef } from 'vue'
    const result = useQuery({ query: QUERY })
    const data = toRef(result, 'data')
    const fetching = toRef(result, 'fetching')
    // 后续直接访问 data.value 即可触发响应
    

2. 模板渲染添加防御性判断

初始加载时data为undefined,直接访问子属性会导致渲染报错,后续数据返回后也无法触发重渲染,需要添加可选链或者条件判断:

<template>
  <!-- 加载状态判断 -->
  <div v-if="result.fetching.value">加载中...</div>
  <div v-else-if="result.error.value">请求出错:{{ result.error.value.message }}</div>
  <!-- 数据访问加可选链 -->
  <TodoItem 
    v-for="item in result.data.value?.privateTodos" 
    :key="item.id" 
    :todo="item"
  />
</template>

3. 检查Urql客户端注册逻辑

确认main.ts中正确注册了Urql客户端到Vue实例,不要遗漏.use(client)调用:

import { createClient, defaultExchanges } from '@urql/vue'

const urqlClient = createClient({
  url: '你的GraphQL接口地址',
  // 未开启SSR不要加ssrExchange,避免数据预取标记异常
  exchanges: defaultExchanges
})

createApp(App).use(urqlClient).mount('#app')

4. 避免同步读取初始值

不要在组件初始化的同步逻辑中直接读取result.data.value,如果需要监听数据返回做额外逻辑,用watch监听数据变化:

watch(() => result.data.value, (newData) => {
  if (newData) {
    // 数据返回后的处理逻辑
  }
}, { deep: true })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:57:01