update
This commit is contained in:
@@ -1,36 +1,58 @@
|
||||
import { createI18n, Composer } from 'vue-i18n';
|
||||
|
||||
// 导入语言文件
|
||||
import enMessages from './locales/en.json';
|
||||
import zhMessages from './locales/zh.json';
|
||||
// 动态导入 locales 目录下的所有 .json 文件
|
||||
// 使用 { eager: true } 确保同步加载,因为 i18n 实例需要在应用初始化时就绪
|
||||
// 使用 { import: 'default' } 直接获取模块的默认导出
|
||||
const localeModules = import.meta.glob('./locales/*.json', { eager: true, import: 'default' });
|
||||
|
||||
// 类型推断 (可选,但推荐)
|
||||
type MessageSchema = typeof enMessages; // 假设 en.json 包含所有 key
|
||||
// 构建 messages 对象和可用语言列表
|
||||
const messages: Record<string, any> = {};
|
||||
const availableLocales: string[] = [];
|
||||
|
||||
// 定义默认语言
|
||||
export const defaultLng = 'en';
|
||||
for (const path in localeModules) {
|
||||
// 从路径中提取语言代码 (例如 './locales/en.json' -> 'en')
|
||||
const locale = path.match(/.\/locales\/(.+)\.json$/)?.[1];
|
||||
if (locale) {
|
||||
messages[locale] = localeModules[path]; // 获取导入的 JSON 内容
|
||||
availableLocales.push(locale);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否成功加载了任何语言文件
|
||||
if (availableLocales.length === 0) {
|
||||
console.error("[i18n] No language files found in './locales/'. Please ensure language files exist and the path is correct.");
|
||||
}
|
||||
|
||||
// 类型推断 (基于第一个加载的语言文件,假设所有文件结构一致)
|
||||
// 如果没有加载到文件,则使用空对象作为 fallback,避免运行时错误
|
||||
type MessageSchema = typeof messages[availableLocales[0]] | {};
|
||||
|
||||
// 定义默认语言 (优先使用 'en',如果不存在则使用第一个找到的语言)
|
||||
export const defaultLng = availableLocales.includes('en') ? 'en' : availableLocales[0] || 'en'; // 添加 'en' 作为最终 fallback
|
||||
const localStorageKey = 'user-locale';
|
||||
|
||||
// 尝试从 localStorage 获取语言,否则回退
|
||||
const getInitialLocaleFromStorage = (): 'en' | 'zh' => {
|
||||
const getInitialLocale = (): string => {
|
||||
const storedLocale = localStorage.getItem(localStorageKey);
|
||||
if (storedLocale === 'en' || storedLocale === 'zh') {
|
||||
// 检查存储的 locale 是否在当前可用的语言列表中
|
||||
if (storedLocale && availableLocales.includes(storedLocale)) {
|
||||
return storedLocale;
|
||||
}
|
||||
// Fallback logic (e.g., browser language or default)
|
||||
// 回退逻辑:检查浏览器语言是否可用
|
||||
const navigatorLang = navigator.language?.split('-')[0];
|
||||
return navigatorLang === 'zh' ? 'zh' : defaultLng;
|
||||
if (navigatorLang && availableLocales.includes(navigatorLang)) {
|
||||
return navigatorLang;
|
||||
}
|
||||
// 最后回退到默认语言
|
||||
return defaultLng;
|
||||
};
|
||||
|
||||
|
||||
const i18n = createI18n<[MessageSchema], 'en' | 'zh'>({
|
||||
const i18n = createI18n<[MessageSchema], string>({ // 使用 string 作为 locale 类型,因为它是动态的
|
||||
legacy: false, // 必须设置为 false 才能在 Composition API 中使用 useI18n
|
||||
locale: getInitialLocaleFromStorage(), // 使用从 localStorage 或回退获取的初始语言
|
||||
locale: getInitialLocale(), // 使用计算得到的初始语言
|
||||
fallbackLocale: defaultLng, // 如果当前语言缺少某个 key,则回退到默认语言
|
||||
messages: {
|
||||
en: enMessages,
|
||||
zh: zhMessages,
|
||||
},
|
||||
messages: messages, // 使用动态构建的 messages 对象
|
||||
// 可选:关闭控制台的 i18n 警告 (例如缺少 key 的警告)
|
||||
// silentTranslationWarn: true,
|
||||
// silentFallbackWarn: true,
|
||||
@@ -38,29 +60,32 @@ const i18n = createI18n<[MessageSchema], 'en' | 'zh'>({
|
||||
|
||||
/**
|
||||
* 设置 i18n 实例的区域设置
|
||||
* @param lang 要设置的语言代码 ('en', 'zh', etc.)
|
||||
* @param lang 要设置的语言代码
|
||||
*/
|
||||
export const setLocale = (lang: 'en' | 'zh') => {
|
||||
console.log(`[i18n] Attempting to set locale to: ${lang}`); // <-- 添加日志
|
||||
const globalComposer = i18n.global as unknown as Composer; // 强制类型断言
|
||||
if (globalComposer.availableLocales.includes(lang)) {
|
||||
const currentLocale = globalComposer.locale.value; // <-- 获取当前 locale
|
||||
if (currentLocale !== lang) { // <-- 仅在 locale 实际改变时更新
|
||||
globalComposer.locale.value = lang; // 访问 .value 属性
|
||||
console.log(`[i18n] Successfully updated global locale from "${currentLocale}" to "${lang}".`); // <-- 修改日志
|
||||
export const setLocale = (lang: string) => {
|
||||
console.log(`[i18n] Attempting to set locale to: ${lang}`);
|
||||
const globalComposer = i18n.global as unknown as Composer;
|
||||
// 使用动态获取的可用语言列表进行检查
|
||||
if (availableLocales.includes(lang)) {
|
||||
const currentLocale = globalComposer.locale.value;
|
||||
if (currentLocale !== lang) {
|
||||
globalComposer.locale.value = lang; // 更新 locale
|
||||
console.log(`[i18n] Successfully updated global locale from "${currentLocale}" to "${lang}".`);
|
||||
try {
|
||||
localStorage.setItem(localStorageKey, lang); // 持久化到 localStorage
|
||||
console.log(`[i18n] Locale "${lang}" saved to localStorage.`); // <-- 修改日志
|
||||
console.log(`[i18n] Locale "${lang}" saved to localStorage.`);
|
||||
} catch (e) {
|
||||
console.error('[i18n] Failed to save locale to localStorage:', e);
|
||||
}
|
||||
} else {
|
||||
console.log(`[i18n] Locale is already "${lang}". No update needed.`); // <-- 添加日志
|
||||
console.log(`[i18n] Locale is already "${lang}". No update needed.`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[i18n] Locale "${lang}" is not available. Available locales: ${globalComposer.availableLocales.join(', ')}`); // <-- 修改日志
|
||||
console.warn(`[i18n] Locale "${lang}" is not available. Available locales: ${availableLocales.join(', ')}`);
|
||||
}
|
||||
};
|
||||
|
||||
// 导出可用语言列表,方便其他地方使用 (例如语言选择器)
|
||||
export { availableLocales };
|
||||
|
||||
export default i18n;
|
||||
|
||||
Reference in New Issue
Block a user