import { createI18n } from 'vue-i18n' import { getCurrentInstance } from 'vue' import zhMessages from './zh' import enMessages from './en' export const i18n = createI18n({ // 定义默认语言 locale: localStorage.getItem('language') || 'zh', fallbackLocale: 'zh', silentTranslationWarn: true, // 去掉警告 messages: { zh: { ...zhMessages }, en: { ...enMessages } }, legacy: true, globalInjection: true, missing: (locale: string, key: string) => { // alert(`${locale} 没有找到翻译 ${key}`) } }) // 创建翻译函数,确保总是能够正确访问到 i18n // 优先使用组件实例的 $t(响应式),否则使用 i18n.global.t const createTranslationFunction = (): ((key: string, ...args: any[]) => string) => { return (key: string, ...args: any[]): string => { // 优先尝试获取当前组件实例的 $t(在 setup 中也能工作,且是响应式的) const instance = getCurrentInstance() if (instance?.proxy?.$t) { return (instance.proxy.$t as any)(key, ...args) } // 否则使用 i18n.global.t(我们导出的正确实例) return (i18n.global.t as any)(key, ...args) } } // 定义 window.$t 的函数 // 直接赋值函数,避免与 vue-i18n 的 defineProperty 冲突 const setupWindowT = () => { if (typeof window === 'undefined') return try { delete (window as any).$t } catch (e) { // ignore } try { ;(window as any).$t = createTranslationFunction() } catch (e) { console.error('定义 window.$t 失败:', e) } } // 初始化 window.$t // if (typeof window !== 'undefined') { // // 立即定义一次 // setupWindowT() // // 简短的智能检查:直接重新定义,无需检查 // let checkCount = 0 // const maxChecks = 20 // 最多检查 2 次,之后停止检查 // const checkTimer = setInterval(() => { // checkCount++ // if (checkCount > maxChecks) { // clearInterval(checkTimer) // return // } // // 直接重新定义,无需检查 // setupWindowT() // }, 100) // } export const mergeMessages = (locale: string, messages: any) => { i18n.global.mergeLocaleMessage(locale, messages) Object.defineProperty(window, '$t', { get: () => (key: string, ...args: any[]) => { return i18n.global.t(key, ...args) }, set: (value) => { // 拦截赋值操作,但允许设置(为了兼容性) // 实际上不会真正设置,getter 总是返回响应式函数 console.warn('window.$t 不应该被重新赋值,已自动恢复为响应式函数') }, configurable: true, enumerable: true }) } window.addEventListener('global-language-change', (e: any) => { const lang = e?.detail?.lang if (lang) { // 使用正确的方式切换语言 // 在 legacy 模式下,locale 可能是 ref 也可能是直接的值 const currentLocale = (i18n.global.locale as any).value ?? i18n.global.locale if (currentLocale !== lang) { if ((i18n.global.locale as any).value !== undefined) { (i18n.global.locale as any).value = lang } else { (i18n.global.locale as any) = lang } } } }) // // 默认的 i18n 实例 // const i18n = createFactoryI18n() // export default i18n