Guide

懒加载翻译

如何懒加载翻译。

对于包含大量翻译内容的应用,最好不要将所有消息打包在主要捆绑包中,而是只懒加载用户选择的语言。
这可以通过 Nuxt i18n 模块 实现,通过让模块知道你的翻译文件所在的位置,以便在应用加载时或用户切换到另一种语言时动态导入它们。
要启用翻译懒加载,请在配置 Nuxt i18n 模块 时遵循以下步骤:

  • lazy 选项设置为 true(如果您想自定义某些选项,可以设置为 配置对象)。
  • langDir 选项设置为包含翻译文件的目录(不能为空)。
  • locales 选项配置为对象数组,每个对象都有一个 filefiles 键,其值是与区域对应的翻译文件。
  • 可选地,删除你可能通过 vueI18n 选项传递给 Vue I18n 的所有消息。
  • 每个 filefiles 可以返回一个 Object,或者返回一个返回 Promise 的函数,该 Promise 必须返回一个 Object

基本用法

示例文件结构:

nuxt-project/
├── lang/
│   ├── en-US.json
│   ├── es-ES.js
│   ├── fr-FR.ts
├── nuxt.config.ts

配置示例:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    locales: [
      {
        code: 'en',
        file: 'en-US.json'
      },
      {
        code: 'es',
        file: 'es-ES.js'
      },
      {
        code: 'fr',
        file: 'fr-FR.ts'
      }
    ],
    lazy: true,
    langDir: 'lang',
    defaultLocale: 'en'
  }
})
lang/fr-FR.ts
export default defineI18nLocale(async locale => {
  return {
    welcome: 'Bienvenue'
  }
})

// 或者

export default {
  welcome: 'Bienvenue'
}
如果你的函数返回一个区域消息的对象,你必须在 defineI18nLocale 组合函数中定义它。关于 defineI18nLocale 的详细信息,请参见 这里

如果函数返回的是在 nuxt i18n 模块中可用的对象,你可以通过 fetch 配置动态区域消息,如 API(包括外部 API)或后端:

export default defineI18nLocale(locale => {
  // 例如,从 nuxt 服务器获取区域消息
  return $fetch(`/api/${locale}`)
})

多文件懒加载

files 属性可用于懒加载多个文件。

这很有用,因为管理多个只定义差异而不重复区域消息的文件效率更高。

例如,让我们考虑支持西班牙语的案例。根据 维基百科,有 20 个国家 在作为官方语言使用西班牙语!

如果这些国家都使用 file 进行配置,则由于每个国家的区域消息重复,维护起来会很困难。

在这种情况下,将所有共享(公共)区域消息保存在一个单独的文件中,以便为每个国家单独定义方言变体,将更容易维护。

以下是包含西班牙语区域文件的 lang 目录的示例:

nuxt-project/
├── lang/
│   ├── es.json     # 西班牙语的公共区域消息
│   ├── es-AR.json  # 阿根廷的区域消息
│   ├── es-UY.json  # 乌拉圭的区域消息
│   ├── es-US.json  # 美国的区域消息
|   ...             # 其他国家 ...
├── nuxt.config.ts

以下是 nuxt.config.ts 中配置的示例:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    locales: [
      /**
       * 以 `files` 定义的西班牙语国家的示例
       */
      {
        code: 'es-AR',
        name: 'Español (Argentina)',
        // 懒加载顺序:`es.json` -> `es-AR.json`,然后将 'es-AR.json' 与 'es.json' 合并
        files: ['es.json', 'es-AR.json']
      },
      {
        code: 'es-UY',
        name: 'Español (Uruguay)',
        // 懒加载顺序:`es.json` -> `es-UY.json`,然后将 'es-UY.json' 与 'es.json' 合并
        files: ['es.json', 'es-UY.json']
      },
      {
        code: 'es-US',
        name: 'Español (Estados Unidos)',
        // 懒加载顺序:`es.json` -> `es-US.json`,然后将 'es-US.json' 与 'es.json' 合并
        files: ['es.json', 'es-US.json']
      }
    ],
    lazy: true,
    langDir: 'lang',
    defaultLocale: 'en'
  }
})

请注意 files 属性的使用,因为上述配置指定了一个包含多个文件名的数组。

@nuxtjs/i18n 将按照 files 中指定的数组顺序懒加载区域消息。然后,它将根据加载的顺序覆盖区域消息。

在上述的 es-AR 示例中,它在 files 中定义了 es.jsones-AR.json。在这种情况下,@nuxtjs/i18n 懒加载 es.json,然后懒加载 es-AR.json 并覆盖 es.json 的区域消息。

在上面的示例中,files 只定义了两个文件,当然你可以指定超过 2 个文件。在这种情况下,文件也将按照数组顺序加载和覆盖。

通过利用区域消息按顺序覆盖的特性,可以通过定义差异性管理区域消息。将共享(公共)区域消息作为 files 的第一个条目添加,然后是区域/方言区域消息的文件条目,可以在避免重复区域消息的同时管理资源。

缓存

懒加载的区域消息是基于其文件名缓存的,filefiles 在区域之间共享,将在加载后使用缓存。默认情况下,静态文件启用缓存,而通过函数返回消息的文件则禁用缓存。

可以通过将 filefiles 的条目设置为具有以下类型签名的对象 { path: string, cache?: boolean} 来按文件配置缓存。以下示例演示了几种有效的文件配置。

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    locales: [
      /**
       * 以 `files` 定义的西班牙语国家的示例
       */
      {
        code: 'es-ES',
        name: 'Español (Spain)',
        // 禁用缓存的文件
        file: { path: 'es.js', cache: false }
      },
      {
        code: 'es-AR',
        name: 'Español (Argentina)',
        // 禁用缓存的文件
        files: [
          { path: 'es.js', cache: false },
          { path: 'es-AR.js', cache: false }
        ]
      },
      {
        code: 'es-UY',
        name: 'Español (Uruguay)',
        // 字符串和对象配置可以混合
        files: [{ path: 'es.js', cache: false }, 'es-UY.json']
      }
    ],
    lazy: true,
    langDir: 'lang',
    defaultLocale: 'en'
  }
})

使用未加载区域的翻译

由于仅加载当前区域的翻译,因此你必须手动加载区域才能使用其翻译。

Nuxt i18n 扩展了 Vue i18n,以提供 loadLocaleMessages 函数来手动加载区域消息,以下示例演示其用法。

const { loadLocaleMessages, t } = useI18n()

await loadLocaleMessages('nl')

const welcome = computed(() => t('welcome')) // Welcome!
const welcomeDutch = computed(() => t('welcome', 1, { locale: 'nl' })) // Welkom!
由于消息可能是从远程 API 加载的,调用 loadLocaleMessages 函数将始终加载消息,不必要的加载可能会影响性能。