主题
国际化
在 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')
这样就可以使用后端来输出翻译数据给前端,即使修改了数据则不需要重新打包