admin-vben5/packages/locales/src/i18n.ts

71 lines
1.5 KiB
TypeScript
Raw Normal View History

2024-05-19 21:20:42 +08:00
import type { Locale } from 'vue-i18n';
import type { ImportLocaleFn, SupportedLanguagesType } from './typing';
2024-06-08 19:49:06 +08:00
2024-05-19 21:20:42 +08:00
import { unref } from 'vue';
import { createI18n } from 'vue-i18n';
const loadedLanguages = new Set<string>();
const i18n = createI18n({
globalInjection: true,
legacy: false,
locale: '',
messages: {},
});
const modules = import.meta.glob('./langs/*.json');
2024-05-19 21:20:42 +08:00
const localesMap = loadLocalesMap(modules);
2024-05-19 21:20:42 +08:00
/**
* Load locale modules
* @param modules
*/
function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
const localesMap: Record<Locale, ImportLocaleFn> = {};
for (const [path, loadLocale] of Object.entries(modules)) {
const key = path.match(/([\w-]*)\.(yaml|yml|json)/)?.[1];
if (key) {
localesMap[key] = loadLocale as ImportLocaleFn;
}
2024-05-19 21:20:42 +08:00
}
return localesMap;
2024-05-19 21:20:42 +08:00
}
/**
* Set i18n language
* @param locale
*/
function setI18nLanguage(locale: Locale) {
i18n.global.locale.value = locale;
document?.querySelector('html')?.setAttribute('lang', locale);
}
/**
* Load locale messages
* @param lang
*/
async function loadI18nMessages(lang: SupportedLanguagesType) {
2024-05-19 21:20:42 +08:00
if (unref(i18n.global.locale) === lang) {
return setI18nLanguage(lang);
}
if (loadedLanguages.has(lang)) {
return setI18nLanguage(lang);
}
const message = await localesMap[lang]?.();
2024-05-19 21:20:42 +08:00
if (message?.default) {
i18n.global.setLocaleMessage(lang, message.default);
}
2024-05-19 21:20:42 +08:00
loadedLanguages.add(lang);
return setI18nLanguage(lang);
}
export { i18n, loadI18nMessages, loadLocalesMap, setI18nLanguage };