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

Nuxt3重新请求服务器数据时子组件Props不更新问题排查

Nuxt3中useFetch请求数据后子组件不更新的问题解决

问题场景

使用最新版本Nuxt3开发时,遇到以下问题:异步请求服务器数据后存入响应式变量,通过props传递给子组件。首次请求正常,但重新请求数据时,父组件的响应式变量已被覆盖,子组件的数据却未更新,无任何变化。

父组件(Index.vue)代码

<script setup> 
import { API_KEY, BASE_URL } from "@/constants/index";

const city = ref("Paris");
const weatherInfo = ref(null);

const getWeatherData = async () => {
  const { data } = await useFetch(
    `${BASE_URL}?q=${city.value}&appid=${API_KEY}`
  );
  weatherInfo.value = data;
};
</script>

<template>
<input
  @keyup.enter="getWeatherData"
  v-model="city"
  type="text"
  class="search"
/>
                
<TheWeatherSummary :weatherInfo="weatherInfo" />
</template>

子组件代码

<script setup>
const props = defineProps({
  weatherInfo: {
    type: [Object, null],
    required: true,
  },
});

</script>

<template>
{{ weatherInfo }}
</template>

对比:原生fetch可正常工作

const getWeatherData = () => {
  fetch(`${BASE_URL}?q=${city.value}&appid=${API_KEY}`)
    .then(res => res.json())
    .then(data => (weatherInfo.value = data))
}

问题原因

Nuxt3的useFetch返回的data是一个响应式ref对象,而非原始的请求数据。当你执行weatherInfo.value = data时,实际上是把这个ref对象本身赋值给了weatherInfo的value,而非ref内部存储的实际数据。

后续重新请求时,虽然data内部的value会更新,但weatherInfo.value指向的还是同一个ref对象,Vue的响应式系统无法检测到引用变化,因此子组件不会触发更新。

而原生fetch返回的是原始JSON对象,每次赋值都是新的对象引用,Vue能检测到这个变化,所以子组件可以正常更新。

解决方案

有两种可行的修改方式:

方式1:获取ref的原始值赋值

修改父组件的getWeatherData方法,将data.value(即ref内部的实际数据)赋值给weatherInfo.value:

const getWeatherData = async () => {
  const { data } = await useFetch(
    `${BASE_URL}?q=${city.value}&appid=${API_KEY}`
  );
  // 赋值ref内部的原始数据,而非ref对象本身
  weatherInfo.value = data.value;
};

方式2:直接使用useFetch返回的响应式变量

不需要额外声明weatherInfo,直接使用useFetch返回的data,并通过refresh方法重新请求:

<script setup> 
import { API_KEY, BASE_URL } from "@/constants/index";

const city = ref("Paris");
// 直接解构获取响应式data和refresh方法
const { data: weatherInfo, refresh } = await useFetch(
  `${BASE_URL}?q=${city.value}&appid=${API_KEY}`
);

const getWeatherData = async () => {
  // 调用refresh重新发起请求,自动更新data的值
  await refresh();
};
</script>

<template>
<input
  @keyup.enter="getWeatherData"
  v-model="city"
  type="text"
  class="search"
/>
                
<TheWeatherSummary :weatherInfo="weatherInfo" />
</template>

两种方式都能确保父组件的响应式变量产生可被Vue检测到的变化,从而触发子组件的更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:57:37