为什么使用VueUse的useFetch获取的数据在组件重新加载时不更新?

爱学习的玉曼 阅读 20

在用VueUse的useFetch请求数据时,发现页面刷新后数据没有重新获取,一直显示旧数据。我尝试手动调用refresh()方法也没反应,控制台也没有报错,这是怎么回事?

我的代码结构大概是这样:


import { useFetch } from 'vueuse'

const { data, refresh } = useFetch('/api/data', {
  immediate: true
})

// 组件挂载后手动刷新
onMounted(() => {
  refresh()
})

// 页面有输入框改变时也调用了refresh()
watch(searchQuery, () => {
  refresh()
})

但无论是页面首次加载还是输入框变化,请求都只在第一次触发,后面都是直接返回缓存结果。我需要每次都能重新发起请求,该怎么解决?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
书生シ育柯
这个问题主要是因为useFetch默认会缓存请求结果,你得告诉它别缓存或者每次都重新请求。复制这个配置就能解决:

import { useFetch } from 'vueuse'

const { data, refresh } = useFetch('/api/data', {
immediate: true,
// 关键是加上这两个选项
cache: false,
dedupe: false
})

// 组件挂载后手动刷新
onMounted(() => {
refresh()
})

// 页面有输入框改变时也调用了refresh()
watch(searchQuery, () => {
refresh()
})


cache设为false是禁用缓存,dedupe设为false是关闭去重。这样每次调用refresh都会重新发起请求。

如果还是不行,可能是你的VueUse版本问题,检查下是不是2.x版本,新版本确实改动了一些行为。顺便吐槽下,这种默认缓存的设计真是反人类,害我debug好久。
点赞
2026-02-18 09:17
技术付楠
你遇到的问题是因为 vueuse 的 useFetch 默认启用了响应式依赖缓存(基于请求 URL 和配置)。如果请求地址没变,它会直接返回缓存结果而不是重新发起请求,尤其是多次调用 refresh() 时容易出现“无变化不触发”的情况。

最直接的解决方式是强制让每次请求的 key 都不同,比如加上时间戳或者随机参数。你可以这样改写:

const { data, refresh } = useFetch(
/api/data?t=${Date.now()},
{ immediate: false }
).get()


注意这里我把 immediate 设为 false,然后手动控制第一次加载。否则 initial 请求不会带时间戳。

更好的写法是封装一个可刷新的 fetch 函数,避免副作用:

const fetchData = () => {
return useFetch(/api/data?t=${Date.now()}).get().json()
}

// 组件中使用
const { data } = fetchData()

watch(searchQuery, () => {
Object.assign(data.value, null) // 清空旧数据(可选)
fetchData().then(res => (data.value = res.data))
})


或者更简洁一点,用 ref 包装请求参数来驱动更新:

const trigger = ref(0)
const url = computed(() => /api/data?_t=${trigger.value})

const { data, refresh } = useFetch(url, { immediate: true }).json()

// 需要刷新时
const reload = () => {
trigger.value++
refresh()
}


这样每次修改 trigger 就能确保 URL 变化,从而绕过缓存。推荐最后这种写法,干净又符合 Vue 响应式设计思路。
点赞 3
2026-02-12 19:00