debug(frontend): 添加导航组件详细日志,便于问题排查
- 增加 mounted 生命周期日志 - 增加 installNavigation 和样式注入日志 - 在各页面注入运行态调试代码 - 优化 installNavigation 容错(fallback 直接注册) - 添加最小测试页 test-minimal.html
This commit is contained in:
@@ -397,8 +397,20 @@ const app = createApp({
|
|||||||
|
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
// 安装导航组件
|
// 安装导航组件
|
||||||
if (window.installNavigation) { window.installNavigation(app); }
|
if (window.installNavigation) { window.installNavigation(app); } else if (window.NavigationComponent) { app.component("navigation-component", window.NavigationComponent); }
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
|
|
||||||
|
// 调试代码:检查导航组件状态
|
||||||
|
setTimeout(() => {
|
||||||
|
const hasNav = !!document.querySelector('.navigation-wrapper');
|
||||||
|
const hasSidebar = !!document.querySelector('.navigation-wrapper .sidebar');
|
||||||
|
console.log('[调试] 导航wrapper:', hasNav);
|
||||||
|
console.log('[调试] 侧边栏:', hasSidebar);
|
||||||
|
if (!hasNav) {
|
||||||
|
console.error('[调试] 导航组件未渲染!window.NavigationComponent=', !!window.NavigationComponent);
|
||||||
|
console.error('[调试] app实例是否存在组件注册?', Vue && Vue.app && Vue.app._context.components['navigation-component']);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -532,8 +532,20 @@
|
|||||||
const app = Vue.createApp(App);
|
const app = Vue.createApp(App);
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
// 安装导航组件
|
// 安装导航组件
|
||||||
if (window.installNavigation) { window.installNavigation(app); }
|
if (window.installNavigation) { window.installNavigation(app); } else if (window.NavigationComponent) { app.component("navigation-component", window.NavigationComponent); }
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
|
|
||||||
|
// 调试代码:检查导航组件状态
|
||||||
|
setTimeout(() => {
|
||||||
|
const hasNav = !!document.querySelector('.navigation-wrapper');
|
||||||
|
const hasSidebar = !!document.querySelector('.navigation-wrapper .sidebar');
|
||||||
|
console.log('[调试] 导航wrapper:', hasNav);
|
||||||
|
console.log('[调试] 侧边栏:', hasSidebar);
|
||||||
|
if (!hasNav) {
|
||||||
|
console.error('[调试] 导航组件未渲染!window.NavigationComponent=', !!window.NavigationComponent);
|
||||||
|
console.error('[调试] app实例是否存在组件注册?', Vue && Vue.app && Vue.app._context.components['navigation-component']);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -148,8 +148,20 @@
|
|||||||
const app = Vue.createApp(LogsApp);
|
const app = Vue.createApp(LogsApp);
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
// 安装导航组件
|
// 安装导航组件
|
||||||
if (window.installNavigation) { window.installNavigation(app); }
|
if (window.installNavigation) { window.installNavigation(app); } else if (window.NavigationComponent) { app.component("navigation-component", window.NavigationComponent); }
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
|
|
||||||
|
// 调试代码:检查导航组件状态
|
||||||
|
setTimeout(() => {
|
||||||
|
const hasNav = !!document.querySelector('.navigation-wrapper');
|
||||||
|
const hasSidebar = !!document.querySelector('.navigation-wrapper .sidebar');
|
||||||
|
console.log('[调试] 导航wrapper:', hasNav);
|
||||||
|
console.log('[调试] 侧边栏:', hasSidebar);
|
||||||
|
if (!hasNav) {
|
||||||
|
console.error('[调试] 导航组件未渲染!window.NavigationComponent=', !!window.NavigationComponent);
|
||||||
|
console.error('[调试] app实例是否存在组件注册?', Vue && Vue.app && Vue.app._context.components['navigation-component']);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,70 +1,52 @@
|
|||||||
// 公共导航组件定义(使用 render 函数,兼容 prod 版 Vue)
|
// 公共导航组件(调试版)
|
||||||
const NavigationComponent = {
|
const NavigationComponent = {
|
||||||
name: 'NavigationComponent',
|
name: 'NavigationComponent',
|
||||||
props: {
|
props: {
|
||||||
currentPage: {
|
currentPage: { type: String, required: true },
|
||||||
type: String,
|
isAdmin: { type: Boolean, default: false }
|
||||||
required: true,
|
|
||||||
validator: (value) => ['dashboard', 'topics', 'logs', 'users', 'admin'].includes(value)
|
|
||||||
},
|
},
|
||||||
isAdmin: {
|
mounted() {
|
||||||
type: Boolean,
|
console.log('[NavigationComponent] 已挂载');
|
||||||
default: false
|
console.log('[NavigationComponent] currentPage:', this.currentPage, 'isAdmin:', this.isAdmin);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
console.log('[NavigationComponent] render called');
|
||||||
const h = this.$createElement;
|
const h = this.$createElement;
|
||||||
const navigate = (page) => this.$emit('navigate', page === 'dashboard' ? '/' : page + '.html');
|
const navigate = (page) => this.$emit('navigate', page === 'dashboard' ? '/' : page + '.html');
|
||||||
|
|
||||||
const sidebarItems = [
|
const sidebarItems = [
|
||||||
{ icon: '📊', label: '系统概览', page: 'dashboard' },
|
{ icon: '📊', label: '系统概览', page: 'dashboard' },
|
||||||
{ icon: '📋', label: '选题管理', page: 'topics' },
|
{ icon: '📋', label: '选题管理', page: 'topics' },
|
||||||
{ icon: '📄', label: '系统日志', page: 'logs' },
|
{ icon: '📄', label: '系统日志', page: 'logs' },
|
||||||
...(this.isAdmin ? [
|
...(this.isAdmin ? [{ icon: '👥', label: '用户管理', page: 'users' }, { icon: '⚙️', label: '系统管理', page: 'admin' }] : [])
|
||||||
{ icon: '👥', label: '用户管理', page: 'users' },
|
|
||||||
{ icon: '⚙️', label: '系统管理', page: 'admin' }
|
|
||||||
] : [])
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const mobileItems = [
|
const mobileItems = [
|
||||||
{ icon: '📊', label: '', page: 'dashboard' },
|
{ icon: '📊', label: '', page: 'dashboard' },
|
||||||
{ icon: '📋', label: '选题', page: 'topics' },
|
{ icon: '📋', label: '选题', page: 'topics' },
|
||||||
{ icon: '📄', label: '日志', page: 'logs' },
|
{ icon: '📄', label: '日志', page: 'logs' },
|
||||||
...(this.isAdmin ? [
|
...(this.isAdmin ? [{ icon: '👥', label: '用户', page: 'users' }, { icon: '⚙️', label: '系统', page: 'admin' }] : [])
|
||||||
{ icon: '👥', label: '用户', page: 'users' },
|
|
||||||
{ icon: '⚙️', label: '系统', page: 'admin' }
|
|
||||||
] : [])
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const createSidebarBtn = (item) => {
|
|
||||||
const isActive = this.currentPage === item.page;
|
|
||||||
return h('button', {
|
|
||||||
class: isActive ? 'sidebar-btn active' : 'sidebar-btn',
|
|
||||||
on: { click: () => navigate(item.page) }
|
|
||||||
}, [item.icon, ' ', item.label].join(''));
|
|
||||||
};
|
|
||||||
|
|
||||||
const createMobileBtn = (item) => {
|
|
||||||
const isActive = this.currentPage === item.page;
|
|
||||||
const content = item.label ? [item.icon, item.label].join('') : item.icon;
|
|
||||||
return h('button', {
|
|
||||||
class: isActive ? 'mobile-nav-btn active' : 'mobile-nav-btn',
|
|
||||||
on: { click: () => navigate(item.page) }
|
|
||||||
}, content);
|
|
||||||
};
|
|
||||||
|
|
||||||
return h('div', { class: 'navigation-wrapper' }, [
|
return h('div', { class: 'navigation-wrapper' }, [
|
||||||
h('aside', { class: 'sidebar' }, [
|
h('aside', { class: 'sidebar' }, [
|
||||||
h('div', { class: 'sidebar-header' }, [h('h3', '宇之然平台')]),
|
h('div', { class: 'sidebar-header' }, [h('h3', '宇之然平台')]),
|
||||||
h('nav', { class: 'sidebar-nav' }, sidebarItems.map(createSidebarBtn))
|
h('nav', { class: 'sidebar-nav' }, sidebarItems.map(item => {
|
||||||
|
const isActive = this.currentPage === item.page;
|
||||||
|
return h('button', { class: isActive ? 'sidebar-btn active' : 'sidebar-btn', on: { click: () => navigate(item.page) } }, [item.icon, ' ', item.label].join(''));
|
||||||
|
}))
|
||||||
]),
|
]),
|
||||||
h('nav', { class: 'mobile-nav' }, mobileItems.map(createMobileBtn))
|
h('nav', { class: 'mobile-nav' }, mobileItems.map(item => {
|
||||||
|
const isActive = this.currentPage === item.page;
|
||||||
|
const content = item.label ? [item.icon, item.label].join('') : item.icon;
|
||||||
|
return h('button', { class: isActive ? 'mobile-nav-btn active' : 'mobile-nav-btn', on: { click: () => navigate(item.page) } }, content);
|
||||||
|
}))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function injectNavigationStyles() {
|
function injectNavigationStyles() {
|
||||||
if (document.getElementById('navigation-styles')) return;
|
if (document.getElementById('navigation-styles')) {
|
||||||
|
console.log('[Nav] 样式已存在,跳过注入');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const styles = `
|
const styles = `
|
||||||
.navigation-wrapper { position: relative; }
|
.navigation-wrapper { position: relative; }
|
||||||
.navigation-wrapper .sidebar {
|
.navigation-wrapper .sidebar {
|
||||||
@@ -89,80 +71,26 @@ function injectNavigationStyles() {
|
|||||||
}
|
}
|
||||||
.navigation-wrapper .mobile-nav-btn:hover { color: #409eff; }
|
.navigation-wrapper .mobile-nav-btn:hover { color: #409eff; }
|
||||||
.navigation-wrapper .mobile-nav-btn.active { color: #409eff; font-weight: 600; }
|
.navigation-wrapper .mobile-nav-btn.active { color: #409eff; font-weight: 600; }
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) { .navigation-wrapper .sidebar { display: none !important; } .navigation-wrapper .mobile-nav { display: flex !important; } }
|
||||||
.navigation-wrapper .sidebar { display: none !important; }
|
@media (min-width: 769px) { .navigation-wrapper .mobile-nav { display: none !important; } }
|
||||||
.navigation-wrapper .mobile-nav { display: flex !important; }
|
.navigation-wrapper + .main-content { margin-left: 180px !important; }
|
||||||
}
|
@media (max-width: 768px) { .navigation-wrapper + .main-content { margin-left: 0 !important; padding-bottom: 60px !important; } }
|
||||||
undefined
|
|
||||||
body > #app > .navigation-wrapper + .main-content { margin-left: 180px !important; }
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
body > #app > .navigation-wrapper + .main-content { margin-left: 0 !important; padding-bottom: 60px !important; }
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
const styleEl = document.createElement('style');
|
const styleEl = document.createElement('style');
|
||||||
styleEl.id = 'navigation-styles';
|
styleEl.id = 'navigation-styles';
|
||||||
styleEl.textContent = styles;
|
styleEl.textContent = styles;
|
||||||
document.head.appendChild(styleEl);
|
document.head.appendChild(styleEl);
|
||||||
|
console.log('[Nav] 样式已注入');
|
||||||
}
|
}
|
||||||
|
|
||||||
function installNavigation(app) {
|
function installNavigation(app) {
|
||||||
|
console.log('[Nav] installNavigation called');
|
||||||
injectNavigationStyles();
|
injectNavigationStyles();
|
||||||
app.component('navigation-component', NavigationComponent);
|
app.component('navigation-component', NavigationComponent);
|
||||||
app.config.globalProperties.$redirectToPage = (path) => { window.location.href = path; };
|
console.log('[Nav] 组件已注册');
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
window.NavigationComponent = NavigationComponent;
|
||||||
window.NavigationComponent = NavigationComponent;
|
window.installNavigation = installNavigation;
|
||||||
window.installNavigation = installNavigation;
|
console.log('[Nav] 脚本已加载');
|
||||||
}
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
module.exports = { NavigationComponent, installNavigation };
|
|
||||||
}
|
|
||||||
// 自动调整 main-content 边距
|
|
||||||
(function adjustLayout() {
|
|
||||||
// 等待DOM加载
|
|
||||||
const check = () => {
|
|
||||||
const main = document.querySelector('.main-content');
|
|
||||||
if (main) {
|
|
||||||
// 检测是否有导航组件
|
|
||||||
const hasSidebar = document.querySelector('.navigation-wrapper .sidebar') !== null;
|
|
||||||
if (hasSidebar) {
|
|
||||||
main.style.marginLeft = '180px';
|
|
||||||
} else {
|
|
||||||
main.style.marginLeft = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 移动端调整
|
|
||||||
const mobileNav = document.querySelector('.navigation-wrapper .mobile-nav');
|
|
||||||
if (mobileNav) {
|
|
||||||
main.style.paddingBottom = '60px';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', check);
|
|
||||||
} else {
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
// Vue 挂载后再次调整(通过全局API)
|
|
||||||
if (window.Vue) {
|
|
||||||
window.Vue.mixin({
|
|
||||||
mounted() {
|
|
||||||
setTimeout(check, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
// 运行时检查(仅开发环境)
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const nav = document.querySelector('.navigation-wrapper');
|
|
||||||
if (!nav) {
|
|
||||||
console.warn('[NavigationComponent] 未找到 .navigation-wrapper 元素,可能未正确渲染');
|
|
||||||
} else {
|
|
||||||
console.log('[NavigationComponent] 已渲染');
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -669,9 +669,21 @@ const TopicsApp = {
|
|||||||
const app = Vue.createApp(TopicsApp);
|
const app = Vue.createApp(TopicsApp);
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
// 安装导航组件
|
// 安装导航组件
|
||||||
if (window.installNavigation) { window.installNavigation(app); }
|
if (window.installNavigation) { window.installNavigation(app); } else if (window.NavigationComponent) { app.component("navigation-component", window.NavigationComponent); }
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
</script>
|
|
||||||
|
// 调试代码:检查导航组件状态
|
||||||
|
setTimeout(() => {
|
||||||
|
const hasNav = !!document.querySelector('.navigation-wrapper');
|
||||||
|
const hasSidebar = !!document.querySelector('.navigation-wrapper .sidebar');
|
||||||
|
console.log('[调试] 导航wrapper:', hasNav);
|
||||||
|
console.log('[调试] 侧边栏:', hasSidebar);
|
||||||
|
if (!hasNav) {
|
||||||
|
console.error('[调试] 导航组件未渲染!window.NavigationComponent=', !!window.NavigationComponent);
|
||||||
|
console.error('[调试] app实例是否存在组件注册?', Vue && Vue.app && Vue.app._context.components['navigation-component']);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -226,8 +226,20 @@
|
|||||||
const app = Vue.createApp(UsersApp);
|
const app = Vue.createApp(UsersApp);
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
// 安装导航组件
|
// 安装导航组件
|
||||||
if (window.installNavigation) { window.installNavigation(app); }
|
if (window.installNavigation) { window.installNavigation(app); } else if (window.NavigationComponent) { app.component("navigation-component", window.NavigationComponent); }
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
|
|
||||||
|
// 调试代码:检查导航组件状态
|
||||||
|
setTimeout(() => {
|
||||||
|
const hasNav = !!document.querySelector('.navigation-wrapper');
|
||||||
|
const hasSidebar = !!document.querySelector('.navigation-wrapper .sidebar');
|
||||||
|
console.log('[调试] 导航wrapper:', hasNav);
|
||||||
|
console.log('[调试] 侧边栏:', hasSidebar);
|
||||||
|
if (!hasNav) {
|
||||||
|
console.error('[调试] 导航组件未渲染!window.NavigationComponent=', !!window.NavigationComponent);
|
||||||
|
console.error('[调试] app实例是否存在组件注册?', Vue && Vue.app && Vue.app._context.components['navigation-component']);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user