V7

语言切换器

@nuxtjs/i18n 在你的应用中加载时,它将你的 locales 配置添加到 this.$i18n (或 app.i18n),这使得在你的应用中任何地方显示语言切换器变得非常容易。

以下是一个语言切换器的示例,其中在每个语言环境对象中添加了 name 键,以便为每个链接显示更友好的标题:

<nuxt-link v-for="locale in availableLocales" :key="locale.code" :to="switchLocalePath(locale.code)">
{{ locale.name }}
</nuxt-link>
computed: {
  availableLocales () {
    return this.$i18n.locales.filter(i => i.code !== this.$i18n.locale)
  }
}
nuxt.config.ts
i18n: {
  locales: [
    {
      code: 'en',
      name: '英语'
    },
    {
      code: 'es',
      name: '西班牙语'
    },
    {
      code: 'fr',
      name: '法语'
    }
  ]
}
使用 detectBrowserLanguage 并希望在路由更改时保持语言环境时,你必须调用其中一个更新存储的语言环境 cookie 的函数。调用 setLocaleCookie(locale) 仅持久化 cookie 语言环境,或 setLocale(locale) 同时持久化 cookie 语言环境并将路由切换到指定的语言环境。否则,在导航期间,语言环境可能会切换回保存的语言环境。

模板代码可能如下所示:

<a href="#" v-for="locale in availableLocales" :key="locale.code" @click.prevent.stop="$i18n.setLocale(locale.code)">
{{ locale.name }}
</a>

动态路由参数

处理动态路由参数需要更多的工作,因为你需要为 @nuxtjs/i18n 提供参数翻译。为此,@nuxtjs/i18n 的 store 模块暴露了一个 routeParams 状态属性,它将在使用 switchLocalePath() 生成语言切换路由时与路由参数合并。

确保你的应用中 启用了 Vuex 并且没有在 @nuxtjs/i18n 的选项中将 vuex 设置为 false

要提供动态参数翻译,请尽早在加载页面时调度 i18n/setRouteParams 突变。传入的对象必须包含 locale code 与给定语言环境下 slug 名称到预期 slug 值的映射。

一个示例(将 postId 替换为适当的路由参数):

<template>
  <!-- pages/post/_postId.vue -->
</template>

<script>
export default {
  async asyncData({ store }) {
    await store.dispatch('i18n/setRouteParams', {
      en: { postId: 'my-post' },
      fr: { postId: 'mon-article' }
    })
  }
}
</script>

请注意,对于名为 _.vue 的特殊情况,该对象的关键字需要设置为 pathMatch。例如:

<template>
  <!-- pages/_.vue -->
</template>

<script>
export default {
  async asyncData({ store }) {
    await store.dispatch('i18n/setRouteParams', {
      en: { pathMatch: 'my-post/abc' },
      fr: { pathMatch: 'mon-article/xyz' }
    })
  }
}
</script>
@nuxtjs/i18n 不会为你重置参数翻译,这意味着如果你在不同路由中使用相同的参数,导航这些路由时可能会导致参数冲突。在这种情况下,请确保始终设置参数翻译。

等待页面过渡

默认情况下,当导航到不同语言环境的路由时,语言环境将立即更改,这意味着如果你有页面过渡,它将淡出页面时文本已经切换到新语言,并以相同内容淡入。

为了解决这个问题,你可以将选项 skipSettingLocaleOnNavigate 设置为 true,并在一个插件中从 beforeEnter 过渡钩子中处理设置语言环境。

nuxt.config.ts
export default {
  plugins: ['~/plugins/router'],

  i18n: {
    skipSettingLocaleOnNavigate: true
  }
}
~/plugins/router.js
export default ({ app }) => {
  app.nuxt.defaultTransition.beforeEnter = () => {
    app.i18n.finalizePendingLocaleChange()
  }

  // 可选:在滚动前等待语言环境以实现更平滑的过渡
  app.router.options.scrollBehavior = async (to, from, savedPosition) => {
    // 确保路由已经更改
    if (to.name !== from.name) {
      await app.i18n.waitForPendingLocaleChange()
    }
    return savedPosition || { x: 0, y: 0 }
  }
}

如果你在页面组件中定义了特定的过渡,你也需要从那里调用 finalizePendingLocaleChange

~/pages/foo.vue
export default {
  transition: {
    beforeEnter() {
      this.$i18n.finalizePendingLocaleChange()
    }
  }
}