- fix(i18n): composition 模式下响应式 locale 在 i18n.global 上(非 i18n.locale), loadLocaleAsync 与 useI18nLazy 改用 i18n.global.locale; useI18nLazy.current 改为派生自全局 locale 的 computed(单一数据源); 各组件 useI18n() 加 useScope:'global' 确保读到同一 composer。 headless 验证:默认中文(不下载EN chunk)->点EN加载en.[hash].js并切英文->切回中文 全通过 - content: 删除 MobileGame 概览中「主要贡献者 Zikai Wang... Hongxiang He...」句子 - timeline: 版本数据改为多演进线并行(zikai-ui/main/doby/roll-a-ball), 每线带 2D/3D 形态标记,3D 线前显示「形态转变:2D -> 3D 滚球」转折标记
51 lines
1.5 KiB
JavaScript
51 lines
1.5 KiB
JavaScript
import { createI18n } from 'vue-i18n'
|
||
import zhCN from './locales/zh-CN.js'
|
||
|
||
// ★ 懒加载设计:创建实例时只同步注入中文(默认语言)。
|
||
// 英文 (en.js) 通过 useI18nLazy 中的动态 import() 按需加载,
|
||
// 被 Vite/Rollup 拆成独立 chunk,只看中文的访客永不下载英文资源。
|
||
const i18n = createI18n({
|
||
legacy: false,
|
||
locale: 'zh-CN',
|
||
fallbackLocale: 'zh-CN',
|
||
messages: {
|
||
'zh-CN': zhCN
|
||
}
|
||
})
|
||
|
||
// 已加载语言集合,避免重复 import
|
||
const loadedLocales = new Set(['zh-CN'])
|
||
|
||
/**
|
||
* 懒加载并切换到目标语言。
|
||
* 首次切换某语言时才动态 import 其语言包并 mergeLocaleMessage,
|
||
* 之后切换仅在已加载集合内完成(无网络请求)。
|
||
*/
|
||
export async function loadLocaleAsync(locale) {
|
||
// composition 模式下响应式 locale 在 i18n.global 上
|
||
if (i18n.global.locale.value === locale) return
|
||
if (loadedLocales.has(locale)) {
|
||
i18n.global.locale.value = locale
|
||
document.documentElement.setAttribute('lang', locale)
|
||
return
|
||
}
|
||
|
||
let messages
|
||
if (locale === 'en') {
|
||
// 动态 import -> 独立 chunk,切换时才下载
|
||
messages = (await import('./locales/en.js')).default
|
||
} else {
|
||
// 未知语言回退到中文
|
||
i18n.global.locale.value = 'zh-CN'
|
||
document.documentElement.setAttribute('lang', 'zh-CN')
|
||
return
|
||
}
|
||
|
||
i18n.global.mergeLocaleMessage(locale, messages)
|
||
loadedLocales.add(locale)
|
||
i18n.global.locale.value = locale
|
||
document.documentElement.setAttribute('lang', locale)
|
||
}
|
||
|
||
export default i18n
|