# 国际化(多语言)

# WEB端

# 语言包定义

  • WEB端项目语言包分为第三方全局页面语言包三种,其中最常用的页面语言包,我们设计了分目录的管理方式。
  • 可以在/src/lang/pages/语言目录下,建立任意目录和语言包文件,程序会自动进行动态批量加载。
  • 以下代码仅为定义和后续的使用演示用示例,以方便读者理解,并非项目实际的语言包文件。
// 公共中文语言包文件 /src/lang/globs-zh-cn.ts
export default {
    // 语言翻译的key请勿带有英文句号(.)
    home: '首页',
}

// 公共英文语言包文件 /src/lang/globs-en.ts
export default {
    home: 'Home',
}

// `终端`的中文语言包文件 /src/lang/pages/zh-cn/terminal.ts(页面语言包)
export default {
    republish: '重新发布',
}

// `终端`的英文语言包文件 /src/lang/pages/en/terminal.ts(页面语言包)
export default {
    republish: 'Republish',
}

# 语言包使用

# 在模板和TS代码中使用

<template>
    <!-- 全局翻译 -->
    <span :title="t('Home')"></span>
    <span>{{ t('Home') }}</span>

    <!-- 页面语言翻译 -->
    <span :title="t('terminal.republish')"></span>
    <span>{{ t('terminal.republish') }}</span>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()

const globs = t('Home') // 获取全局翻译
const pages = t('terminal.republish') // 获取页面语言翻译
</script>

# 仅在模板中使用

<template>
    
    <!-- 全局翻译 -->
    <span :title="$t('Home')"></span>
    <span>{{ $t('Home') }}</span>

    <!-- 页面语言翻译 -->
    <span :title="$t('terminal.republish')"></span>
    <span>{{ $t('terminal.republish') }}</span>
</template>

<script setup lang="ts"></script>

# 实现介绍

  • web端的国际化使用了vue-i18n实现。
  • 我们只加载了当前环境对应的语言包,比如zh-cn的所有语言包文件,或者en的所有语言包文件(所以切换语言包,站点会自动刷新)
  • element-plus的语言包,我们只载入了中文英文,若需支持element-plus的其他语言包,请自行在/@/lang/index文件中添加。
  • 我们在main.js文件中调用/@/lang/index文件内的loadLang函数对所有语言包进行了加载。
  • /@/lang/index文件中,我们利用import.meta.globEager批量加载了element公共页面的语言包文件,目前暂无好的仅加载当前页面语言包的办法。
  • 页面语言包,支持无限目录层级加载,我们根据对应目录结构,实现了以.分隔的语言翻译key,比如:/@/lang/pages/zh-cn/auth/menu.ts语言包定义如下:
export default {
    name: '名称',
}
// 使用该语言翻译
// 它的格式是:目录.目录.翻译key
t('auth.menu.name')

重要提示

WEB端语言翻译的key请勿带有英文句号(.

# server端

SERVER端使用了Thinkphp6自带的多语言功能,并做了适当封装。

# 语言包定义

  • 一个应用下的语言包目录结构类似于:
app/admin/lang
├─lang
│  │  en.php 应用公共英文语言包
│  │  zh-cn.php 应用公共中文语言包
│  │  
│  ├─en
│  │  │  index.php Index控制器英文语言包
│  │  │  
│  │  └─user
│  │          moneylog.php user/MoneyLog控制器英文语言包
│  │          
│  └─zh-cn
│      │  index.php Index控制器中文语言包
│      │  
│      └─user
│              moneylog.php user/MoneyLog控制器中文语言包
  • 我们已经在app\common\controller\ApiApi基类中,实现了对应控制器的语言包自动加载,所以可以直接使用语言翻译,而无需额外的语言包加载。


以下代码仅为定义和后续的使用演示用示例,以方便读者理解,并非项目实际的语言包文件。

// 应用公共英文语言包文件
// app/admin/lang/en.php
return [
    'Hello %s' => 'Hello,%s',
    "Hello %s, I'm %s" => "Hello %s, I'm %s",
];

// 应用公共中文语言包文件
// app/admin/lang/zh-cn.php
return [
    'Hello %s' => '你好,%s',
    "Hello %s, I'm %s" => "你好%s,我是%s",
];

# 语言包使用

  • 我们定义了全局公共函数__,来进行语言翻译:

函数定义:

/**
 * 语言翻译
 * @param string $name 被翻译字符
 * @param array  $vars 替换字符数组
 * @param string $lang 指定翻译语言
 * @return string
 */
__(string $name, array $vars = [], string $lang = '');

函数使用:

__('Hello %s', ['BuildAdmin']);
__('Hello %s', ['BuildAdmin'], 'en');
__("Hello %s, I'm %s", ['BuildAdmin', '妙码生花'], 'zh-cn');

# 加载说明

  • 如果控制器继承了app\common\controller\Api,则可以实现语言包按控制器自动加载

# 假设当前为中文语言环境

# 访问
https://buildadmin.com/index.php/admin/auth.admin/index
# 自动加载语言包
app/admin/lang/zh-cn.php
app/admin/lang/zh-cn/auth/admin.php

有时我们需要在当前控制器导入其他语言包文件,可以参考以下代码进行加载:

$langset = $this->app->lang->getLangSet();
$this->app->lang->load([
    app_path() . 'lang' . DIRECTORY_SEPARATOR . $langset . DIRECTORY_SEPARATOR . (str_replace('/', DIRECTORY_SEPARATOR, $this->app->request->controllerPath)) . '.php'
]);