语言切换器

@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: 'English'
    },
    {
      code: 'es',
      name: 'Español'
    },
    {
      code: 'fr',
      name: 'Français'
    }
  ]
}
使用 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 的存储模块公开了一个 routeParams 状态属性,它会在使用 switchLocalePath() 生成语言切换路由时与路由参数合并。

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

要提供动态参数翻译,请在加载页面时尽早调用 i18n/setRouteParams 变更。传入的对象必须包含从区域设置 code 到带有从声明名称到特定区域设置的预期声明值的对象的映射。

一个示例(将 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()
    }
  }
}