语言切换器
当 @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()
}
}
}