Skip to content

国际化

v4.2.5 版本中,专业版已经将后台语言数据使用后端提供,使用 laravel 框架的多语言功能。在根目录下lang目录。目前包含两个语言

  • zh
  • en

目录结构如下

php
├─lang
  ├─zh (中文)
  |  generate.php
|  |  login.php
  |  module.php
  |  register.php
  |  system.php
  ├─en (英文)
  |  generate.php
|  |  login.php
  |  module.php
  |  register.php
  |  system.php

规定以文件名作为某个功能模块的 key 使用,所以具体实现如下

php
public function translate($lang)
{
    //return admin_cache('lang_'.$lang, 300, function () use ($lang) {
        $translations = [];
        $files = File::allFiles(lang_path($lang));

        foreach ($files as $file) {
            $translations[$file->getFilenameWithoutExtension()] = require $file->getRealPath();
        }


        return $translations;
    // });
}

WARNING

默认是不使用缓存的,如果需要,你可以打开缓存,毕竟文件查找得过程是需要耗费时间,尤其是数据多了之后得情况下

前端还是在i18n目录下,跟之前的有所区别,但区别不大,只是加入异步加载得功能,具体实现如下

js
import Cache from '@/support/cache'
import { createI18n } from 'vue-i18n'
import type { App } from 'vue'
import http from '@/support/http'

// 语言包缓存的键名
const LANG_CACHE_KEY = 'cached_lang_pack_'

// 创建i18n实例
const i18n = createI18n({
  locale: Cache.get('language') || 'zh',
  fallbackLocale: 'zh',
  globalInjection: true,
  legacy: false,
  messages: {} // 初始化为空对象,语言包将从后端加载
})

// 扩展 i18n 类型
declare module 'vue-i18n' {
  interface I18n {
    loadLanguage: (lang: string) => Promise<boolean>
  }
}

/**
 * 从后端加载语言包
 * @param locale 语言代码
 * @returns Promise<boolean> 加载是否成功
 */
const loadTranslations = async (locale: string): Promise<boolean> => {
    // 如果没有缓存,从后端获取语言包
    try {
      const response = await http.get(`/lang/${locale}`)

      if (response.data && response.data.data) {
        // 设置语言包
        i18n.global.setLocaleMessage(locale, response.data.data)

        // 更新当前语言
        i18n.global.locale.value = locale

        // 保存语言设置到缓存
        Cache.set('language', locale)

        // 缓存语言包数据
        Cache.set(`${LANG_CACHE_KEY}${locale}`, response.data.data)

        return true
      }
      return false
    } catch (error) {
      // 如果是默认语言且没有缓存,则失败
      if (locale === 'zh') {
        return false
      }
      return loadTranslations('zh')
    }
}

// 将 loadLanguage 方法挂载到 i18n 对象上
i18n.loadLanguage = loadTranslations

/**
 * 初始化i18n
 * @param app Vue应用实例
 */
export async function bootstrapI18n(app: App): Promise<void> {
  // 加载默认语言包
  const defaultLocale = Cache.get('language') || 'zh'

  try {
    // 尝试加载默认语言包
    const success = await loadTranslations(defaultLocale)

    // 如果默认语言加载失败且不是中文,尝试加载中文
    if (!success && defaultLocale !== 'zh') {
      await loadTranslations('zh')
    }
  } catch (error) {
    // 如果加载失败,创建一个空的语言包以避免应用崩溃
    i18n.global.setLocaleMessage('zh', {})
    i18n.global.locale.value = 'zh'
  }

  // 注册i18n插件
  app.use(i18n)
}

export default i18n

当然这整个过程还是需要前后端配合的,前端依旧使用 t 函数进行多语言翻译。所以整个开发过程中,前后端需要定义好翻译的 key,前端使用

js
// t 函数进行翻译
t('generate.code.xxxx.xxxx')

这样就可以使用后端来输出翻译数据给前端,即使修改了数据则不需要重新打包