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

Nuxt切换i18n语言时asyncData拉取的数据未正常更新

问题原因

首先你看到的Observer对象不是异常数据:

  • Nuxt 2基于Vue 2实现,所有挂载到组件上的响应式数据都会被Vue包裹为Observer对象用于依赖收集。首次加载首页时asyncData在服务端执行,打印的是未经过响应式处理的原始数据;切换语言走客户端路由跳转时,asyncData在客户端执行,返回的数据会被Vue做响应式转换,所以控制台显示Observer标记是正常现象,你展开对象能看到正确的法语内容就证明接口请求本身是成功的。

页面内容消失是你的代码存在几个明确问题:

  • 语言映射逻辑有漏洞:三个独立的if判断没有兜底规则,一旦i18n当前locale值和判断条件不完全匹配(比如葡萄牙语配置的code是pt-PT而非pt),传给接口的lang参数就会是undefined,接口返回不符合预期的数据。
  • 异常捕获逻辑缺失:catch块仅打印错误,没有返回符合结构的兜底数据,一旦请求出现异常,组件内的projects/articles/services变量会变成undefined,模板访问属性时直接抛出JS错误导致页面空白。
  • 同路由组件复用问题:切换语言时URL仅变化语言前缀,Nuxt默认会复用页面组件实例,部分场景下会导致数据更新不触发视图重渲染。
  • 原生fetch的错误捕获漏洞:fetch仅在网络故障时抛出异常,接口返回4xx/5xx状态码时不会进入catch,容易出现返回数据格式异常的问题。
修复方案

按以下步骤修改代码即可解决问题:

  1. 替换零散的if判断为映射表,增加默认语言兜底,避免lang参数异常:
// 替换原来的三个if判断
const langMap = {
  en: 'en',
  pt: 'pt-PT',
  'pt-PT': 'pt-PT',
  fr: 'fr'
}
const lang = langMap[i18n.locale] || 'en'
  1. 封装统一的请求方法,增加HTTP状态码校验,用Promise.all并行请求提升加载速度,同时修正catch块返回固定结构的兜底数据:
async asyncData({ store, i18n }) {
  const langMap = {
    en: 'en',
    pt: 'pt-PT',
    'pt-PT': 'pt-PT',
    fr: 'fr'
  }
  const lang = langMap[i18n.locale] || 'en'

  // 统一请求方法
  const fetchStrapi = async (path) => {
    const res = await fetch(`${store.state.apiUrl}${path}&locale=${lang}`)
    if (!res.ok) throw new Error(`接口请求失败,状态码:${res.status}`)
    return res.json()
  }

  try {
    // 并行请求,比逐个await速度更快
    const [services, projects, articles] = await Promise.all([
      fetchStrapi('/project-categories?populate=*'),
      fetchStrapi('/projects?populate=*'),
      fetchStrapi('/articles?populate=*')
    ])

    return {
      projects: projects.data,
      articles: articles.data,
      services: services.data
    }
  } catch (error) {
    console.log(error)
    // 兜底返回空数组,保证模板访问属性不会报错
    return {
      projects: [],
      articles: [],
      services: []
    }
  }
}
  1. 解决同路由组件复用问题:找到项目布局文件(默认是layouts/default.vue),将原来的<nuxt />组件增加$route.fullPath作为key,保证路由(含语言参数)变化时组件强制刷新:
<!-- 原来的<nuxt />替换为下面的写法 -->
<nuxt :key="$route.fullPath" />
  1. 检查模板中的属性访问路径是否正确:Strapi v4返回的条目属性都在attributes字段下,比如渲染项目标题需要写{{ project.attributes.title }},不要漏写attributes层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:54:17