跳到主要内容

国际化多语言

场景​

  • 1、切换多语言
  • 2、app内嵌h5页面,app切换语言时,h5也需要多语言切换
  • 3、获取语言可以多种方式
    • h5中手动切换语言
    • 内嵌的app中,可通过请求头、cookie等方式获取当前语言,和客户端/后端约定好

相关方法​

  • useI18n

    • mergeLocaleMessage动态合并语言对象,用于合并多语言数据
  • useLocalePath

    • localePath接收两个参数,一个是目标路由,一个是目标语言,根据当前语言区域解析路径
    • 用于生成路径跳转链接,生成带有语言前缀的路径
  • defineI18nRoute

    • 为当前页面路由定义每种语言下的路径(slug),适合处理不同语言页面 URL 不一致

    • 想让中文路径是 /guanyu,英文路径是 /about,就可以这样做

      js
      defineI18nRoute({
      paths: {
      en: '/about',
      zh: '/guanyu'
      }
      })

每个页面多语言切换​

一般情况下,会在根目录定义一个通用的多语言文件,每个页面都可以读取在根目录定义好的多语言,但是有些页面需要展示额外不同的多语言,那么页面上需要自定义多语言文件,按页面来加载不同语言

  • 1、全局通用语言:全局通用的多语言,定义在根目录的lang
  • 2、页面特地语言:在每个页面定义一个lang为文件夹,来存放多语言
js
├── lang/ # 全局通用语言文件
│ ├── en.json
│ └── zh-CN.json
├── pages/
│ └── about/ # 示例页面
│ ├── lang/ # 页面级语言文件
│ │ ├── en.json
│ │ └── zh-CN.json
│ └── index.vue

在页面加载特定语言​

  • mergeLocaleMessage(locale, messages):动态合并语言对象
    • 可将当前语言 locale 合并到已注册的语言环境信息中
ts
<template>
{{ $t("welcome") }}
{{ $t("username") }}
</template>

<script setup lang="ts">
const { locale, mergeLocaleMessage } = useI18n()

async function loadPageMessages(lang: string) {
const pageMessages = await import(`~/pages/home/locales/${lang}.json`)
mergeLocaleMessage(lang, pageMessages.default)
}

// 初始加载 (保证在客户端和服务端都执行,避免闪烁)
await loadPageMessages(locale.value)

// 切换语言时重新加载
watch(locale, async (newLang) => {
await loadPageMessages(newLang)
})
</script>

URL多语言前缀配置​

配置 strategy​

  • 路由策略

选项说明:

  • 默认是英文en,不加前缀
值说明示例 URL(默认语言为 en)
'prefix'所有语言都加前缀/en, /ja
'prefix_except_default' ✅默认语言不加前缀,其它加/(en),/ja
'prefix_and_default'所有语言都加前缀,包括默认语言/en, /ja
'no_prefix'所有语言都不加前缀(仅用 cookie/localStorage 管控)/(始终),不能用于 SEO

懒加载语言资源​

  • 配置lazy设置为ture
  • 是否按需加载语言 JSON 文件(而不是一次性加载所有语言)。

i18n 配置文件​

  • i18n/i18n.config.ts
    • 可以在 <rootDir>/i18n 目录中创建一个 i18n.config.ts 文件

i18n遇到问题坑​

  • NuxtLink会存在问题,跳转会丢失当前语言路由
    • 解决:用i18n提供的NuxtLinkLocale替代NuxtLink

注意点以及优化​

  • 避免重复加载多语言
    • 如缓存
  • 自动化加载自定义的多语言
    • 如通过插件,自动监听当前路由, 来加载当前路由页面的多语言
  • 多语言的按需加载
    • 减少多语言的打包体积
  • SSR的兼容性
  • 注意语言的加载情况, 避免出现闪烁
    • 为什么会出现闪烁? 比如第一次加载全局的语言包,第二次加载页面级别的特定的语言包
    • 首次渲染的时候,首先会执行服务端渲染ssr, 服务端生成HTML页面结构之后,给到客户端,这时候客户端才会执行相关方法
    • 避免使用onBeforeMount、onMounted来加载语言包,因为这2个hooks是在客户端执行,可能会出现闪烁情况 (因为需要等到第二次在执行)
    • 解决方法:
      • 1、直接在setup执行,在服务端渲染和客户端都会执行一样逻辑
      • 2、使用watch监听来动态加载切换语言包