4a76561a85
- 将时区列表提取到独立常量文件 `timezone.js` 中,便于维护和扩展 - 重构时间戳显示逻辑,将初始化功能从事件处理器中分离 - 引入 timerManager、eventManager 和 scriptManager 进行资源统一管理 - 更新 DOM 操作方式,使用 window.eventManager 替代直接 addEventListener - 改进时间戳更新函数,支持传入元素引用以提高灵活性 - 在路由加载脚本时增加调试日志,方便追踪组件加载过程 - 移除冗余的 DOM 工具函数(如 getElementById),统一使用原生方法 - 修复计时器清理问题,确保通过 timerManager 正确清除定时任务 - 初始化时间戳和日期输入框默认值,提升用户体验
138 lines
3.2 KiB
JavaScript
138 lines
3.2 KiB
JavaScript
import { TimerManager } from '../utils/timerManager.js';
|
|
import { EventManager } from '../utils/eventManager.js';
|
|
import { ScriptManager } from '../utils/scriptManager.js';
|
|
|
|
class Router {
|
|
constructor() {
|
|
this.routes = {};
|
|
this.beforeFun = null;
|
|
this.afterFun = null;
|
|
this.routerViewId = 'app';
|
|
this.redirectRoute = null;
|
|
this.stackPages = true;
|
|
this.routerMap = [];
|
|
this.historyFlag = '';
|
|
this.history = [];
|
|
this.scriptManager = window.scriptManager;
|
|
this.eventManager = window.eventManager;
|
|
this.timerManager = window.timerManager;
|
|
}
|
|
|
|
/**
|
|
* 初始化路由
|
|
*/
|
|
init(config) {
|
|
// 配置路由
|
|
this.routerMap = config?.routes || this.routerMap;
|
|
this.routerViewId = config?.routerViewId || this.routerViewId;
|
|
this.stackPages = config?.stackPages ?? this.stackPages;
|
|
this.map();
|
|
|
|
// 监听路由变化
|
|
window.addEventListener('hashchange', () => this.urlChange());
|
|
window.addEventListener('load', () => this.urlChange());
|
|
window.lintTo = (path) => this.naviage(path);
|
|
}
|
|
|
|
map() {
|
|
if (!this.routerMap.length) {
|
|
console.error('请配置路由');
|
|
return;
|
|
}
|
|
|
|
for (const r of this.routerMap) {
|
|
if (r.name == 'redirect') this.redirectRoute = r.path;
|
|
this.routes[r.path] = r;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 导航
|
|
*/
|
|
naviage(path) {
|
|
window.location.hash = path;
|
|
}
|
|
|
|
/**
|
|
* 路由解析与渲染
|
|
*/
|
|
urlChange() {
|
|
const path = location.hash.replace('#', '') || this.redirectRoute;
|
|
console.log('当前路由:', path);
|
|
const route = this.routes[path];
|
|
|
|
if (!route) {
|
|
location.hash = this.redirectRoute;
|
|
return;
|
|
}
|
|
|
|
const doChange = async () => {
|
|
this.timerManager.cleanAll();
|
|
this.eventManager.removeAll();
|
|
|
|
const mount = document.getElementById(this.routerViewId);
|
|
if (!mount) {
|
|
console.error('挂载点不存在:', this.routerViewId);
|
|
return;
|
|
}
|
|
|
|
if (!this.stackPages) mount.innerHTML = '';
|
|
|
|
if (route.html) {
|
|
try {
|
|
const html = await fetch(route.html).then((r) => r.text());
|
|
mount.innerHTML = html;
|
|
} catch (e) {
|
|
mount.innerHTML = `<h2>页面加载失败:${e.message}</h2>`;
|
|
}
|
|
}
|
|
|
|
console.log('当前组件:', route.script);
|
|
if (route.script) {
|
|
await this.scriptManager.loadScript({
|
|
path: route.script,
|
|
name: route.name,
|
|
isModule: route.isModule,
|
|
deps: route.deps,
|
|
});
|
|
}
|
|
|
|
console.log('当前组件:', route.name);
|
|
await this.scriptManager.runInit(route.name);
|
|
|
|
this.currentRoute = route;
|
|
if (this.afterFun) this.afterFun(route);
|
|
};
|
|
|
|
if (this.beforeFun) {
|
|
this.beforeFun({ to: route, next: doChange });
|
|
} else {
|
|
doChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* before 钩子
|
|
*/
|
|
beforeEach(callback) {
|
|
if (typeof callback === 'function') {
|
|
this.beforeFun = callback;
|
|
} else {
|
|
console.trace('beforeEach 必须是函数');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* after 钩子
|
|
*/
|
|
afterEach(callback) {
|
|
if (typeof callback === 'function') {
|
|
this.afterFun = callback;
|
|
} else {
|
|
console.trace('afterEach 必须是函数');
|
|
}
|
|
}
|
|
}
|
|
|
|
export { Router };
|