// #ifdef H5 import './common/js/pc' // #endif import Vue from 'vue' import App from './App' import store from './store' import Util from './common/js/util.js' import Http from './common/js/http.js' import Lang from './common/js/lang.js' import Config from './common/js/config.js' import EventBus from './common/js/event-bus.js' import DomEventBridge from './common/js/dom-event-bridge.js' import globalConfig from './common/js/golbalConfig.js'; import { uniStorage } from './common/js/storage.js' import configExternal from './common/js/config-external.js' import PrivacyManager from './common/js/privacy.js' import splashState from './common/js/splash-state.js' Vue.prototype.$store = store //挂在vue Vue.config.productionTip = false Vue.prototype.$util = Util; Vue.prototype.$api = Http; Vue.prototype.$langConfig = Lang; //语言包对象 Vue.prototype.$lang = Lang.lang; //解析语言包 Vue.prototype.$config = Config; Vue.prototype.$privacy = PrivacyManager; //全局隐私管理器 // #ifdef H5 EventBus.setDomBridge(DomEventBridge) // #endif Vue.prototype.$eventBus = EventBus; Vue.mixin(globalConfig); // 远端 i18n 翻译热更新:复用项目原有"componentRefresh"机制(同 diy.js 下拉刷新) // lang.js 在翻译覆写更新时 commit('setComponentRefresh'), // golbalConfig.js 已把 componentRefresh 注册为全局 computed, // 在此 watch 它并 $forceUpdate,触发所有页面内 {{$lang('xxx')}} 重新求值 Vue.mixin({ watch: { componentRefresh() { this.$forceUpdate(); } } }); // 鸿蒙元服务环境: 全局接管 onTabItemTap, 兜底系统 TabBar 点击 // 背景: 鸿蒙下 uni.switchTab 对系统 TabBar 点击静默失败 // 通过全局 mixin 覆盖所有未显式定义 onTabItemTap 的页面(子包动态 tab 页等), // 显式定义 onTabItemTap 的页面(如 pages/empty/index.vue、index.js)优先级高于此 mixin // #ifdef MP-HARMONY Vue.mixin({ onTabItemTap(e) { console.log('[TabBar][HARMONY] global onTabItemTap fired:', e); if (!e || !e.pagePath) return; const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; const currentPath = currentPage ? '/' + currentPage.route : ''; const targetPath = e.pagePath.startsWith('/') ? e.pagePath : '/' + e.pagePath; console.log('[TabBar][HARMONY] onTabItemTap currentPath=', currentPath, 'targetPath=', targetPath); // 已经在目标页则不重复跳转 if (currentPath === targetPath) return; // 用干净路径(不带 query), 避免 HarmonyOS 对带 query 的 tabBar 跳转有兼容性问题 uni.reLaunch({ url: targetPath, success: () => console.log('[TabBar][HARMONY] global reLaunch success:', targetPath), fail: (err) => console.error('[TabBar][HARMONY] global reLaunch fail:', targetPath, err) }); } }); // #endif App.mpType = 'app'; // 重写存储,增加前缀 uniStorage(); // 组件已改为按需引入,不再全局注册 // ============================================================ // 平台差异处理: // H5: 可在 $mount() 前 await boot, 首屏直接有翻译 // 小程序/鸿蒙: App() 必须同步注册, $mount() 不能推迟 // → 同步 $mount() + lang() 短路返回空串 + boot 完成后 $forceUpdate // // 以下代码所有平台共享: // - lang.js: bootCompleted 标志, boot 未完成时 lang() 返回空串 // - http.js: sendRequest 门控, boot 未完成时业务请求排队 // - splash-state.js: 统一启动屏状态 (H5 降级 uni.showLoading, 小程序/鸿蒙走 splash 组件) // - App.vue: onLaunch 中 splashState.show() + await boot + splashState.hide() // ============================================================ // #ifdef H5 // H5: remote-only 下先 await boot 再 $mount(), 首屏直接有翻译数据 // splashState.show() 内部 H5 降级为 uni.showLoading (await 期间 Vue 还没挂载,组件层无法渲染) async function bootstrap() { if (Lang.isRemoteOnly && Lang.isRemoteOnly()) { splashState.show(); try { await Lang.boot(); } catch (e) { console.warn('[i18n] remote-only boot fail', e); } finally { splashState.hide({ reason: 'boot-complete' }); } } const app = new Vue({ ...App, store }); app.$mount(); } bootstrap() // #endif // #ifndef H5 // 小程序/鸿蒙: 同步 $mount(), boot 在 App.vue onLaunch 中异步执行 // lang() 在 boot 未完成时返回空串, boot 完成后 emitUpdated 触发 $forceUpdate const app = new Vue({ ...App, store }); app.$mount(); // #endif