为什么捐赠
API 浏览器
联系站长
多语言国际化(i18n)

国际化是一种设计理念,确保产品(网站或应用程序)无需修改源代码即可适配各种语言和地区。可以把国际化理解为"为本地化做好准备"。

TIP

推荐使用 vue-i18n 来完成多语言国际化。需要通过 @quasar/app-vite Boot 文件@quasar/app-webpack Boot 文件来引入它。在 Boot 文件文档页面中,您可以找到引用 vue-i18n 的具体示例。

WARNING

Quasar 文档假定您已经熟悉 vue-i18n 的用法。下面只讲解在 Quasar CLI 项目中的基本使用方式。完整的功能列表请查看 Vue I18n 文档

手动安装

如果您在使用 yarn create quasar(或 npm init quasar@latest、pnpm 或 Bun 等效命令)创建项目时没有启用 i18n,可以按照以下步骤手动安装。

  1. 安装 vue-i18n 依赖。

$ yarn add vue-i18n
  1. 创建 src/boot/i18n.js 文件,内容如下:

import { defineBoot } from '#q-app/wrappers'
import { createI18n } from 'vue-i18n'
import messages from 'src/i18n'

export default defineBoot(({ app }) => {
  const i18n = createI18n({
    locale: 'en-US',
    globalInjection: true,
    messages
  })

  // 将 i18n 实例注册到 app 中
  app.use(i18n)
})
  1. 创建一个文件夹 (/src/i18n/) 用于存放支持的多语言文案。例如:src/i18n。注意第二步中的 import messages from 'src/i18n',这一步就是编写被导入内容的地方。

  2. 然后在 quasar.configboot 部分引用这个文件:

/quasar.config file

return {
  boot: [
    // ...
    "i18n",
  ],

  // ...
};

现在已经准备好了,可以在项目中使用了。

在 SFC 中配置翻译标签
仅 @quasar/app-vite

WARNING

以下内容仅适用于使用 @quasar/app-vite 的项目!

如果您想在 Quasar CLI 项目的 SFC(单文件组件)中使用 <i18n> 标签,需要修改现有配置。

首先安装 @intlify/unplugin-vue-i18n 包:


$ yarn add --dev @intlify/unplugin-vue-i18n

然后编辑 /quasar.config 文件:

/quasar.config file

import { fileURLToPath } from "node:url";

// ...

build: {
  vitePlugins: [
    [
      "@intlify/unplugin-vue-i18n/vite",
      {
        // 如果要使用 Vue I18n Legacy API,需要设置 `compositionOnly: false`
        // compositionOnly: false,

        // 如果要在 Vue I18n 消息中使用命名 token,如 'Hello {name}',
        // 需要设置 `runtimeOnly: false`
        // runtimeOnly: false,

        ssr: ctx.modeName === "ssr",

        // 您需要设置 i18n 资源的路径!
        include: [fileURLToPath(new URL("./src/i18n", import.meta.url))],
      },
    ],
  ];
}

如何使用

下面是一个展示主要用法的示例:

<template>
  <q-page>
    <!-- 文本插值,响应式 -->
    {{ $t('hello') }}

    <!-- 属性绑定,响应式 -->
    <q-btn :label="$t('hello')" />

    <!-- v-html 指令用法 -->
    <span v-html="content"></span>
  </q-page>
</template>

<script setup>
  import { computed } from "vue";
  import { useI18n } from "vue-i18n";

  const { t } = useI18n();

  // 绑定到静态变量,非响应式
  // const staticContent = t('hello')
  // 绑定到响应式变量,但只赋值一次,语言切换时不会更新
  // const reactiveStaticContent = ref(t('hello'))

  // 绑定到响应式变量,语言切换时会自动更新
  const content = computed(() => t("hello"));

  function notify() {
    Notify.create({
      type: "positive",
      message: t("hello"),
    });
  }
</script>

添加新的语言

假设您要添加德语。

  1. 创建新文件 src/i18n/de/index.js,将 src/i18n/en-US/index.js 文件中的内容复制过去,然后修改对应的语言字符串。
  2. 修改 src/i18n/index.js,添加新的 de 语言。
import enUS from "./en-US";
import de from "./de";

export default {
  "en-US": enUS,
  de: de,
};

语言切换示例

Some Vue file

<template>
  <!-- ...... -->
  <q-select
    v-model="locale"
    :options="localeOptions"
    label="Quasar Language"
    dense
    borderless
    emit-value
    map-options
    options-dense
    style="min-width: 150px"
  />
  <!-- ...... -->
</template>

<script setup>
  import { useI18n } from 'vue-i18n'

  const { locale } = useI18n({ useScope: 'global' })

  const localeOptions: [
    { value: 'en-US', label: 'English' },
    { value: 'de', label: 'German' }
  ]
</script>

UPPERCASE

许多语言(如希腊语、德语和荷兰语)有不直观的大写规则,有一些边界情况您应该了解:

QBtn 组件会使用 CSS text-transform: uppercase 规则将其 label 自动转为全大写。按照 MDN 文档的说法,“语言由 lang HTML 属性或 xml:lang XML 属性定义”。但遗憾的是,各浏览器的实现并不一致,而且 2017 年 ISO 标准中的大写德语 eszett 字母 ß 尚未被广泛采纳。目前有两种解决方案:

  1. 使用 no-caps 属性,放弃自动大写,按期望的样式直接书写字符串
  2. 使用 no-caps 属性,通过 $q.lang.getLocale() 获取当前语言环境,并使用 toLocaleUpperCase 方法重写字符串

检测地区

Quasar 也提供了一个开箱即用的方法来检测用户所在的地区:

// 在 Vue 文件之外使用
import { Lang } from 'quasar'
Lang.getLocale() // 返回一个字符串

// 在 Vue 文件之内
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()
  $q.lang.getLocale() // 返回一个字符串
}

WARNING

如果您使用了 Quasar 的 set 方法($q.lang.set()),它不会反映到 Quasar 的 getLocale 上。原因是 getLocale() 始终返回用户所在的地区(基于浏览器设置)。set() 方法设置的是 Quasar 内部的语言配置,用于决定使用哪个语言文件。如果您想查看通过 set() 设置的语言,可以使用 $q.lang.isoName