当 @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)
}
}
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()
生成语言切换路由时与路由参数合并。
要提供动态参数翻译,请尽早在加载页面时调度 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>
默认情况下,当导航到不同语言环境的路由时,语言环境将立即更改,这意味着如果你有页面过渡,它将淡出页面时文本已经切换到新语言,并以相同内容淡入。
为了解决这个问题,你可以将选项 skipSettingLocaleOnNavigate
设置为 true
,并在一个插件中从 beforeEnter
过渡钩子中处理设置语言环境。
export default {
plugins: ['~/plugins/router'],
i18n: {
skipSettingLocaleOnNavigate: true
}
}
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
。
export default {
transition: {
beforeEnter() {
this.$i18n.finalizePendingLocaleChange()
}
}
}