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
相关产品推荐
相关产品推荐

