Guide

语言切换器

如何更改您网站的当前语言。

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: '英语'
      },
      {
        code: 'es',
        name: '西班牙语'
      },
      {
        code: 'fr',
        name: '法语'
      }
    ]
  }
})
要在使用 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 应用,您可以使用 NuxtPagetransition 来控制它,如下所示:

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>

可选地,在滚动之前等待语言,以获得更平滑的过渡,方法是使用 Router Options:

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() 定义了特定的过渡,并需要在 pageTransitiononBeforeEnter 钩子中添加 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。