Skip to content

Nuxt 3 集成

我们推荐使用 Nuxt I18n (@nuxtjs/i18n) 来在 Nuxt 3 中使用 Vue I18n,它提供了诸如本地化路由、SEO 标签等高级功能。

创建你自己的 Nuxt 3 集成

以下是通过添加 Vue I18n 作为 Nuxt 插件来设置带有自己集成的 Nuxt 3 应用程序的教程。

注意

本集成教程不支持高级 i18n 功能(如路由和 SEO 标签),仅用于演示目的,请考虑使用 Nuxt I18n 模块,详细信息请参见 i18n.nuxtjs.org 文档。

要求

本教程的 Node.js 要求与 Nuxt 3 相同。

请查看 此处 了解 Nuxt 3 的 Node.js 版本要求。

示例代码

你可以在 examples/frameworks/nuxt3 找到本教程的代码。

你也可以查看一个按照此教程制作的已部署应用程序,该应用使用自定义的 GitHub Actions 从 DeepL 提供翻译,项目地址为 nuxt3-app-vue-i18n

在 Nuxt 3 应用程序上设置 vue-i18n

我们现在将设置使用 Vue I18n 与 Nuxt 3 的初始环境。

创建 Nuxt 3 应用程序

运行以下命令创建 Nuxt 3 应用程序:

sh
npx nuxi init nuxt3-app-vue-i18n
sh
pnpm dlx nuxi init nuxt3-app-vue-i18n

运行以上命令后,创建的 Nuxt 3 初始项目将具有以下目录结构:

txt
cd nuxt3-app-vue-i18n
tree -L 1
.
├── README.md
├── app.vue
├── nuxt.config.ts
├── package.json
└── tsconfig.json

安装 Vue I18n

使用以下命令安装 Vue I18n:

sh
npm install vue-i18n -D
sh
yarn add vue-i18n -D
sh
pnpm add -D vue-i18n

设置 Nuxt 插件

按如下方式创建 plugins 目录:

sh
mkdir plugins

接下来,创建一个 Nuxt 插件文件来设置 Vue I18n。

sh
touch plugins/i18n.ts

创建后,按如下方式定义插件:

ts
import { createI18n } from 'vue-i18n'

export default defineNuxtPlugin(({ vueApp }) => {
  const i18n = createI18n({
    legacy: false,
    globalInjection: true,
    locale: 'en',
    messages: {
      en: {
        hello: 'Hello, {name}!'
      }
    }
  })

  vueApp.use(i18n)
})

有关本地化 Nuxt 3 应用程序的区域资源配置,将在 下一节 中描述

运行 Nuxt 3 应用程序

让我们看看 Vue I18n 是否能与 Nuxt 3 一起工作。

我们将编辑设置好的 Nuxt 3 应用程序的 app.vue,如下所示:

vue
<template>
  <div>
    <NuxtWelcome /> // [!code --]
    <h1>{{ $t('hello', { name: 'vue-i18n' }) }}</h1> // [!code ++]
  </div>
</template>

编辑并保存后,运行以下命令在本地运行 Nuxt 3 应用程序:

sh
npm run dev
sh
yarn dev
sh
pnpm dev

当应用程序在 http://localhost:3000 上运行时,我们会看到如下内容:

Nuxt3 setup

本地化你的 Nuxt 3 应用程序

到目前为止,我们已经能够将 Vue I18n 集成到我们的 Nuxt 3 应用程序中。现在让我们实现语言切换并从外部导入区域资源。

通过实现语言切换,我们实际上使 Nuxt 3 应用程序具有了 i18n 功能。🌎 🌍 🌏

此外,当我们把区域资源从源码中分离出来(使其外部化),我们可以借助本地化服务使用独立的工作流程来本地化应用程序。

在以下章节中,我们将在我们的 Nuxt 3 应用程序中启用英语、法语和日语的支持。

添加语言切换

我们将按如下方式在 app.vue 中添加语言切换功能:

vue
<template>
  <div>
    <h1>{{ $t('hello', { name: 'vue-i18n' }) }}</h1>
    <form>
      <label for="locale-select">{{ $t('language') }}: </label> // [!code ++]
      <select
        id="locale-select"
        v-model="$i18n.locale"
      >
        <option value="en">
          en
        </option> // [!code ++]
        <option value="fr">
          fr
        </option> // [!code ++]
        <option value="ja">
          ja
        </option> // [!code ++]
      </select> // [!code ++]
    </form> // [!code ++]
  </div>
</template>

使用 form 中的 select 元素实现了语言切换。 每个选项的值定义为区域代码的值,稍后将在区域资源外部化的部分进行解释。

每个选项的值定义了区域代码的值,稍后将在区域资源外部化的部分进行解释。

外部化区域资源

我们将把区域资源配置为外部的。

Vue I18n 支持多种资源文件格式,在这种情况下我们选择 JSON 格式。

通过运行以下命令创建一个名为 locales 的非 "Nuxt-3-standard" 目录:

sh
mkdir locales

现在,让我们为想要支持的每种语言创建 JSON 文件:

sh
touch locales/en.json # 英语
touch locales/fr.json # 法语
touch locales/ja.json # 日语

用以下内容填充它们:

对于英语在 locales/en.json

json
{
  "hello": "Hello, {name}!",
  "language": "Language"
}

对于法语在 locales/fr.json

json
{
  "hello": "Bonjour, {name}!",
  "language": "Langue"
}

对于日语在 locales/ja.json

json
{
  "hello": "こんにちは、{name}!",
  "language": "言語"
}

导入区域资源

让我们在插件 (plugins/i18n.ts) 中注册这些区域:

js
import { createI18n } from 'vue-i18n'
import en from '../locales/en.json'
import fr from '../locales/fr.json'
import ja from '../locales/ja.json'

export default defineNuxtPlugin(({ vueApp }) => {
  const i18n = createI18n({
    legacy: false,
    globalInjection: true,
    locale: 'en',
    messages: {
      en: { 
        hello: "Hello, {name}!"
      } 
      en, 
      fr, 
      ja 
    }
  })

  vueApp.use(i18n)
})

messages 选项将保存我们注册的区域资源,其粒度可以根据需要调整。这种细粒度便于与本地化服务集成。

让我们运行 npm run dev(或 yarn devpnpm dev)并前往 http://localhost:3000 查看更改是否生效。

Setup i18n on Nuxt3

Nuxt 3 应用程序现在已经准备好进行基本的国际化了!🎉

使用 @intlify/unplugin-vue-i18n 优化

到目前为止,你已经能够使用 Vue I18n 在 Nuxt 3 应用程序中支持语言切换。另外,通过将区域资源外部化,你已经将它们与源代码分离开来,这使得更容易管理区域资源并与本地化服务集成。

然而,正如 优化 中所述,迄今为止准备的 Nuxt 3 应用程序在打包大小方面表现不佳。

自从 Vue I18n v9 以来,消息编译器允许预编译区域资源以提高性能,但尚未为此优化性能。

进入 @intlify/unplugin-vue-i18n - 一个用于优化 Vue I18n 性能的插件。

安装 @intlify/unplugin-vue-i18n

sh
npm install @intlify/unplugin-vue-i18n -D
sh
yarn add @intlify/unplugin-vue-i18n -D
sh
pnpm add -D @intlify/unplugin-vue-i18n

配置 Nuxt 配置

按如下方式配置 nuxt.config.ts

js
import { defineNuxtConfig } from 'nuxt'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'url'
import VueI18nVitePlugin from '@intlify/unplugin-vue-i18n/vite'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  build: { 
    transpile: ['vue-i18n'] 
  }, 
  vite: { 
    plugins: [ 
      VueI18nVitePlugin({ 
        include: [ 
          resolve(dirname(fileURLToPath(import.meta.url)), './locales/*.json') 
        ] 
      }) 
    ] 
  } 
})

Nuxt 3 的默认捆绑器是 vite。因此我们将在这里使用 vite 选项进行优化。

vite.plugins 中,配置了 @intlify/unplugin-vue-i18n 插件。该插件的一个选项 include 指定了放置在 locales 目录中的 JSON 格式的区域资源。这允许 @intlify/unplugin-vue-i18n 在打包时使用 Vue I18n 消息编译器预编译区域资源。这提高了 Vue I18n 的翻译性能,进而提高了 Nuxt 3 应用程序的渲染性能。

内部捆绑优化

完成设置后,运行 npm run dev 来检查!

访问 http://localhost:3000 后,Nuxt 3 应用程序的行为保持不变,但在带宽方面有所变化。

下图是使用和不使用 @intlify/unplugin-vue-i18n 时在开发工具网络标签中测量的包大小比较:

减少包大小

蓝色突出显示的区域是 vite 打包的代码。

通过设置此插件,插件会内部设置仅运行时的 Vue I18n 模块。具体来说,vite 配置 resolve.aliasvue-i18n 别名设置为仅使用 Vue I18n 运行时(vue-i18n/dist/vue-i18n.runtime.esm-bundler.js)。通过不包含 Vue I18n 使用的消息编译器,此设置减少了包大小。

详情请见 @intlify/unplugin-vue-i18n 文档

同时,你可以看到区域资源打包的变化。

根据是否在 vite.plugins 中设置了 @intlify/unplugin-vue-i18n 插件,区域资源的代码会有所不同。如下所示:

预编译

如果不设置 @intlify/unplugin-vue-i18n 插件到 vite.plugins,区域资源会被打包为 json,但设置了该插件后,区域资源会 从 json 转换为 JavaScript 代码 以减少带宽。

Vue I18n 只需调用已编译的函数即可。

在本指南中,Nuxt 3 应用程序较小,所以可能无法充分体验优化的性能,但随着应用程序变得更大,它肯定会带来好处。