语言切换器
如何更改网站的当前语言。
当 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>
nuxt.config.ts
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>
等待页面过渡
默认情况下,当导航到不同语言环境的路由时,语言环境将立即更改,这意味着如果你有页面过渡,它将使页面淡出,文本已切换到新语言,然后淡入相同的内容。
为了解决这个问题,你可以将选项 skipSettingLocaleOnNavigate 设置为 true,并在插件中定义的 onBeforeEnter 过渡钩子中自行处理语言环境设置。
全局过渡
如果你想过渡整个 Nuxt 应用程序,你可以使用 NuxtPage 的 transition 来控制它,如下所示:
nuxt.config.ts
export default defineNuxtConfig({
i18n: {
// ... 你的其他选项
skipSettingLocaleOnNavigate: true
}
}
pages/app.vue
<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>
可选:在滚动前等待语言环境,以实现更流畅的过渡,使用 路由选项:
app/router.options.ts
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。
示例:
pages/about.vue
<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>
Vue i18n 注意事项
与 Vue i18n 不同,你不应该直接设置 locale,而应该使用 setLocale() 或导航到 switchLocalePath() 返回的路由来切换语言。这会加载翻译,触发钩子,并在使用时更新语言环境 cookie。