1. 修复多处页面onTabItemTap事件,使用uni.reLaunch兜底鸿蒙下switchTab静默失败的问题 2. 全局混入onTabItemTap兜底未手动处理的页面 3. 优化路由跳转逻辑,针对鸿蒙环境增加switchTab失败兜底和超时强制跳转 4. 优化可选链调用和空值判断,提升代码健壮性
133 lines
4.5 KiB
JavaScript
133 lines
4.5 KiB
JavaScript
// #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
|