refactor: separate story locales (public/) from UI locales (src/), async fetch for story messages

This commit is contained in:
2026-06-10 12:10:03 +08:00
parent 0071a34acf
commit 4cf2263c78
7 changed files with 219 additions and 186 deletions

View File

@@ -1,29 +1,62 @@
import { ref } from 'vue'
import zh from '@/locales/zh.json'
import en from '@/locales/en.json'
import ja from '@/locales/ja.json'
import zhUI from '@/locales/zh.json'
import enUI from '@/locales/en.json'
import jaUI from '@/locales/ja.json'
const messages = { zh, en, ja } as const
const uiMessages = { zh: zhUI, en: enUI, ja: jaUI } as const
type Lang = 'zh' | 'en' | 'ja'
const currentLang = ref<Lang>(
(localStorage.getItem('lang') as Lang) || 'zh'
(localStorage.getItem('lang') as Lang) || 'zh',
)
export function useI18n() {
function t(key: string): string {
const parts = key.split('.')
let result: any = messages[currentLang.value]
for (const p of parts) {
result = result?.[p]
const storyMessages = ref<Record<string, Record<string, any>>>({})
const storyLoading = new Set<Lang>()
async function loadStoryMessages(lang: Lang) {
if (storyMessages.value[lang] || storyLoading.has(lang)) return
storyLoading.add(lang)
try {
const resp = await fetch(`/locales/${lang}.json`)
if (resp.ok) {
storyMessages.value = {
...storyMessages.value,
[lang]: await resp.json(),
}
}
return typeof result === 'string' ? result : key
} catch {
/* story locales optional */
} finally {
storyLoading.delete(lang)
}
}
function setLang(lang: Lang) {
currentLang.value = lang
localStorage.setItem('lang', lang)
loadStoryMessages(currentLang.value)
function t(key: string): string {
const parts = key.split('.')
let result: any = storyMessages.value[currentLang.value]
for (const p of parts) {
result = result?.[p]
}
if (typeof result === 'string') return result
let fallback: any = uiMessages[currentLang.value]
for (const p of parts) {
fallback = fallback?.[p]
}
if (typeof fallback === 'string') return fallback
return key
}
async function setLang(lang: Lang) {
await loadStoryMessages(lang)
currentLang.value = lang
localStorage.setItem('lang', lang)
}
export function useI18n() {
return { t, currentLang, setLang }
}