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

Pinia中useFetch数据无法自动刷新,页面不更新求助

问题

修改v-text-field绑定的body.title时,网络面板显示请求成功并返回新数据,但页面数据未更新。直接在Vue组件的async setup()内使用useFetch时页面能正常更新,将useFetch放到Pinia store中则失效。补充信息:

  • Pinia中useFetch的onResponse回调能看到新数据,但无法通过return response._data将数据带出
  • 改用$fetch后,修改body.title甚至无网络请求,似乎$fetch不监听body参数

原因分析

  1. Pinia与useFetch的响应式断联:useFetch返回的_data是响应式Ref,但你仅做了一次data.value = _data.value赋值,后续_data更新时,Pinia的data无法自动同步。同时固定key: 'rooms'会触发Nuxt的缓存机制,导致后续请求复用旧数据。
  2. $fetch无自动监听逻辑:$fetch是普通HTTP请求工具,本身不会监听body的变化,需手动触发请求才会发起调用。
  3. 组件未触发重新请求:当前组件仅在onMounted时调用一次fetch,修改body.title后没有重新触发请求,这是页面不更新的直接原因。

解决方案

方案1:修复Pinia中useFetch的响应式关联

修改Pinia store的fetch函数,移除固定key避免缓存干扰,并通过onResponse直接同步数据:

export const useRoomStore = defineStore('roomStore', () => {
  const body = ref<IRoomBody>(ROOM_BODY_DEFAULT)
  const data = ref<any>([])

  const fetch = async () => {
    await useFetch('/api/rooms', {
      method: 'post',
      body,
      onRequest({ options }) {
        const token = localStorage.getItem('access_token')
        const headers = new Headers(options.headers)
        headers.set('Content-Type', 'application/json')
        if (token) headers.set('Authorization', `Bearer ${token}`)
        options.headers = headers
      },
      // 请求完成后直接更新Pinia的data
      onResponse({ response }) {
        data.value = response._data
      }
    })
  }

  return {
    body,
    data,
    fetch
  }
})

方案2:组件监听body变化,自动触发请求

在Vue组件中添加watch监听body变化,自动重新调用fetch:

<script lang="ts">
import { useRoomStore } from '@/stores/RoomStore'
import { watch, onMounted } from 'vue'

export default defineComponent({
  setup() {
    const roomStore = useRoomStore()
    const { fetch } = roomStore
    const { data, body } = storeToRefs(roomStore)

    onMounted(() => {
      fetch()
    })

    // 监听body变化,自动触发请求
    watch(body, async () => {
      await fetch()
    }, { deep: true }) // 若body是复杂对象,需开启deep监听

    return {
      body,
      data,
    }
  },
})
</script>

方案3:$fetch的正确使用方式

若坚持使用$fetch,手动处理请求逻辑,并同样监听body变化触发请求:

// Pinia store的fetch函数
const fetch = async () => {
  const token = localStorage.getItem('access_token')
  const res = await $fetch('/api/rooms', {
    method: 'post',
    body: body.value,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': token ? `Bearer ${token}` : ''
    }
  })
  data.value = res
}

组件部分同样添加watch监听body变化,确保修改body.title时发起新请求。

关键注意点

  • useFetch是Nuxt带缓存的响应式请求工具,避免固定key导致缓存复用旧数据
  • 无论使用useFetch还是$fetch,都需要手动监听请求参数变化来触发新请求
  • 使用storeToRefs获取Pinia数据是正确的,确保组件能追踪到响应式变化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:52:37