语言切换器
当Nuxt i18n 模块在您的应用中加载时,它将您的 locales
配置添加到 nuxtApp.$i18n
(或 this.$i18n
),这使得在您应用的任何地方显示语言切换器变得非常容易。
这是一个语言切换器的示例,其中为每个语言环境对象添加了一个 name
键,以便为每个链接显示更友好的标题:
<script setup>
const { locale, locales } = useI18n()
const switchLocalePath = useSwitchLocalePath()
const availableLocales = computed(() => {
return locales.value.filter(i => i.code !== locale.value)
})
</script>
<template>
<NuxtLink v-for="locale in availableLocales" :key="locale.code" :to="switchLocalePath(locale.code)">
{{ locale.name }}
</NuxtLink>
</template>
export default defineNuxtConfig({
i18n: {
locales: [
{
code: 'en',
name: 'English'
},
{
code: 'es',
name: 'Español'
},
{
code: 'fr',
name: 'Français'
}
]
}
})
detectBrowserLanguage
时在路由变化时保持语言环境,您必须明确更新存储的语言环境 cookie。可以使用 setLocaleCookie(locale)
或 setLocale(locale)
来设置 cookie 并切换到指定语言环境的路由。如果不这样做,可能会导致基于所设置的语言环境 cookie 在导航时进行重定向。模板代码可能看起来像这样,例如:
<script setup>
const { locale, locales, setLocale } = useI18n()
const availableLocales = computed(() => {
return locales.value.filter(i => i.code !== locale.value)
})
</script>
<template>
...
<a href="#" v-for="locale in availableLocales" :key="locale.code" @click.prevent.stop="setLocale(locale.code)">
{{ locale.name }}
</a>
...
</template>
动态路由参数
处理动态路由参数需要更多的工作,因为您需要为Nuxt i18n 模块提供参数的翻译。可组合的 useSetI18nParams
可以用于设置路由参数的翻译,这用于设置 SEO 标签以及更改 switchLocalePath
返回的路由。
已渲染的组件不会因页面和树下方组件的更改而更新。相反,这些链接在客户端在水合期间更新,在大多数情况下这不会造成问题。
SEO 标签情况不同,这些标签在 SSR 期间会正确更新,无论何时何地设置 i18n 参数。
查看实验性的
switchLocalePathLinkSSR
特性,结合 <SwitchLocalePathLink>
组件,无论何时何地使用,它都能在 SSR 期间正确呈现链接。一个示例(将 slug
替换为适用的路由参数):
<script setup>
// 从 API 获取产品...(红色杯子)
const setI18nParams = useSetI18nParams()
setI18nParams({
en: { slug: data.slugs.en }, // slug: 'red-mug'
nl: { slug: data.slugs.nl } // slug: 'rode-mok'
})
const switchLocalePath = useSwitchLocalePath()
switchLocalePath('en') // /products/red-mug
switchLocalePath('nl') // /nl/products/rode-mok
</script>
<template>
<!-- pages/products/[slug].vue -->
</template>
请注意,对于像 [...pathMatch.vue]
这样的捕获所有路由,对象的键需要是 pathMatch
。例如:
<script>
const setI18nParams = useSetI18nParams()
setI18nParams({
en: { pathMatch: ['not-found-my-post'] },
fr: { pathMatch: ['not-found-mon-article'] }
})
</script>
<template>
<!-- pages/[...pathMatch].vue -->
</template>
请注意,捕获所有路由被定义为 数组。在这个例子中,只有一个元素,但如果您想使用子路径,例如 /not-found/post
,则需要定义多个元素,如 ['not-found', 'post']
。您需要定义多个,例如 ['not-found', 'post']
。
等待页面过渡
默认情况下,当导航到具有不同语言环境的路由时,语言环境会立即更改,这意味着如果您有页面过渡,它将以新语言的文本淡出页面,再以相同内容淡入。
要解决此问题,您可以将选项 skipSettingLocaleOnNavigate
设置为 true
,并在插件中定义的 onBeforeEnter
过渡钩子中自行处理设置语言环境。
全局过渡
如果您想对整个 Nuxt 应用进行过渡,可以使用 NuxtPage
的 transition
来控制,如下所示:
export default defineNuxtConfig({
i18n: {
// ... 您的其他选项
skipSettingLocaleOnNavigate: true
}
}
<script setup lang="ts">
const { finalizePendingLocaleChange } = useI18n()
const onBeforeEnter = async () => {
await finalizePendingLocaleChange()
}
</script>
<template>
<NuxtLayout>
<NuxtPage
:transition="{
name: 'my',
mode: 'out-in',
onBeforeEnter
}"
/>
</NuxtLayout>
</template>
<style>
.my-enter-active,
.my-leave-active {
transition: opacity 0.3s;
}
.my-enter,
.my-leave-active {
opacity: 0;
}
</style>
可选的,在平滑过渡之前等待语言环境的设置,使用 Router Options:
import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig>{
async scrollBehavior(to, from, savedPosition) {
const nuxtApp = useNuxtApp()
// 确保路由已更改。
if (nuxtApp.$i18n && to.name !== from.name) {
// `$i18n` 在 nuxtjs/i18n 模块的 `setup` 中注入。
// `scrollBehavior` 被保护,即使未完成也不会被调用
await nuxtApp.$i18n.waitForPendingLocaleChange()
}
return savedPosition || { top: 0 }
}
}
每页面组件过渡
如果您在页面组件中使用 definePageMeta
定义了特定的过渡,并且需要在 pageTransition
的 onBeforeEnter
钩子中添加 finalizePendingLocaleChange
。
示例:
<script setup lang="ts">
const route = useRoute()
const { finalizePendingLocaleChange } = useI18n()
definePageMeta({
pageTransition: {
name: 'page',
mode: 'out-in'
}
})
route.meta.pageTransition.onBeforeEnter = async () => {
await finalizePendingLocaleChange()
}
</script>
<style scoped>
.page-enter-active,
.page-leave-active {
transition: opacity 1s;
}
.page-enter,
.page-leave-active {
opacity: 0;
}
</style>
definePageMeta
的动态路由参数(已弃用) 使用
动态参数可以使用 definePageMeta
进行配置。在使用 switchLocalePath()
生成语言切换路由时,这些参数将与路由参数合并。
dynamicRouteParams
设置为 true
以启用动态路由参数。示例(将 id
替换为适用的路由参数):
<script setup>
definePageMeta({
// ...
nuxtI18n: {
en: { id: 'my-post' },
fr: { id: 'mon-article' }
}
// ...
})
</script>
<template>
<!-- pages/post/[id].vue -->
</template>
请注意,对于像 [...pathMatch.vue]
这样的捕获所有路由,对象的键需要是 pathMatch
。例如:
<script>
definePageMeta({
// ...
nuxtI18n: {
en: { pathMatch: ['not-found-my-post'] },
fr: { pathMatch: ['not-found-mon-article'] }
}
// ...
})
</script>
<template>
<!-- pages/[...pathMatch].vue -->
</template>
Vue i18n 注意事项
与 Vue i18n 相比,您不应直接设置 locale
,而应通过使用 setLocale
或导航到由 switchLocalePath
返回的路由来切换语言。这样可以加载翻译,触发钩子,并在使用时更新语言环境 cookie。