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

Vue3异步拉取数据在locale切换时无法更新问题

问题原因

核心问题出在两层逻辑错误:

  1. 原fetchData工具函数每次调用都会返回一个全新创建的ref实例,函数内部的异步请求只会更新这个内部ref的value,不会同步给外层变量。首次加载能正常渲染,是因为初始化时外层fetchedData的value指向第一个内部ref,请求完成后内部ref更新,视图碰巧能读取到值;但语言切换时,你给fetchedData.value赋值的是新创建的第二个内部ref对象,视图不会自动追踪这个新ref内部的value变化,自然不会更新。
  2. 原逻辑没有对异步请求做统一的状态管理,既无法判断请求完成时机,也存在locale切换时store内语言值未同步更新,导致拉取到旧语言数据的边缘问题。
修复步骤

1. 改造fetchData工具函数

移除工具函数内部的ref创建逻辑,改成标准异步函数,直接返回请求结果,响应式状态统一交给组件维护,从根源避免嵌套ref问题:

// utils/universal-fetch.js
export async function fetchData(section, key) {
  const requestConfig = {
    method: "GET",
    headers: { "Content-Type": "application/json" },
  };

  const response = await fetch(
    `http://localhost:4000/api/${section}/?api-key=${key}`,
    requestConfig
  );
  const data = await response.json();

  if (!response.ok) {
    const errorMsg = data?.message || response.statusText;
    throw new Error(errorMsg);
  }

  return data;
}

2. 调整组件内调用逻辑

组件内统一维护响应式状态,封装独立的数据加载方法,在初始化和语言切换时调用,等请求完成后再更新数据:

<script setup>
import { fetchData } from "../../utils/universal-fetch";
import { ref, watch, onMounted } from "vue";
import { useStore } from "../../stores/language.js";
import { useI18n } from "vue-i18n";
import AOS from "aos";

const store = useStore();
const { locale } = useI18n({ useScope: "global" });

// 响应式状态直接在组件内初始化,不要嵌套其他ref
const fetchedData = ref(null);
const loading = ref(false); // 可选:加加载状态优化交互

// 封装统一的数据拉取逻辑
const loadHomeSectionData = async () => {
  loading.value = true;
  try {
    const res = await fetchData("homeFirstSection", store.getLanguage);
    fetchedData.value = res;
  } catch (error) {
    console.error("数据拉取失败:", error);
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  AOS.init();
  loadHomeSectionData();
});

// 监听语言变化重新拉取数据
watch(
  () => locale.value,
  () => {
    loadHomeSectionData();
  }
);
</script>
可选优化

如果不想在onMounted里单独调用首次加载,可以给watch加immediate: true配置,组件初始化时会自动触发一次加载逻辑,代码更简洁:

watch(
  () => locale.value,
  () => {
    loadHomeSectionData();
  },
  { immediate: true }
);

加了这个配置就可以删掉onMounted里的loadHomeSectionData()调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:18:14