/** * 极简 hash 路由 */ import { t } from './lib/i18n.js' const routes = {} const _moduleCache = {} let _contentEl = null let _loadId = 0 let _currentCleanup = null let _initialized = false let _defaultRoute = '/dashboard' export function registerRoute(path, loader) { routes[path] = loader } export function setDefaultRoute(path) { _defaultRoute = path } export function navigate(path) { const current = window.location.hash.slice(1) window.location.hash = path // 如果 hash 没有实际变化,手动触发加载(引擎切换等场景兜底) if (current === path) { reloadCurrentRoute() } } export function initRouter(contentEl) { _contentEl = contentEl if (!_initialized) { window.addEventListener('hashchange', () => loadRoute()) _initialized = true } loadRoute() } async function loadRoute() { const hash = window.location.hash.slice(1) || _defaultRoute const routePath = hash.split('?')[0] const loader = routes[routePath] if (!loader || !_contentEl) return // 竞态防护:记录本次加载 ID const thisLoad = ++_loadId // 清理上一个页面 if (_currentCleanup) { try { _currentCleanup() } catch (_) {} _currentCleanup = null } // 立即移除旧页面(不等退出动画,消除切换卡顿) _contentEl.innerHTML = '' // 已缓存的模块:跳过 spinner,直接渲染 let mod = _moduleCache[routePath] if (!mod) { _contentEl.innerHTML = '' // 仅首次加载显示 spinner const spinnerEl = document.createElement('div') spinnerEl.className = 'page-loader' spinnerEl.innerHTML = `