add
This commit is contained in:
@@ -1,19 +1,177 @@
|
||||
/* 侧边栏组件 */
|
||||
import { menuConfig } from '../config/menu.js';
|
||||
import { Router } from '../core/router.js';
|
||||
/**
|
||||
* 侧边栏菜单组件
|
||||
*/
|
||||
window.Sidebar = {
|
||||
/**
|
||||
* 初始化侧边栏
|
||||
* @param {jQuery} container - 容器元素
|
||||
*/
|
||||
init(container) {
|
||||
this.container = container;
|
||||
this.collapse = localStorage.getItem(SystemConfig.menuCollapseKey) === 'true';
|
||||
this.renderMenu();
|
||||
this.bindEvents();
|
||||
this.updateCollapseState();
|
||||
},
|
||||
|
||||
export function renderSidebar() {
|
||||
const sidebar = document.createElement('div');
|
||||
sidebar.className = 'sidebar';
|
||||
|
||||
// 渲染菜单
|
||||
const menuHtml = menuConfig.map(item => `
|
||||
<div class="menu-item" onclick="Router.push('${item.path}')">
|
||||
<i class="icon-${item.icon}"></i>
|
||||
<span>${item.name}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
sidebar.innerHTML = menuHtml;
|
||||
return sidebar;
|
||||
}
|
||||
/**
|
||||
* 渲染菜单
|
||||
*/
|
||||
renderMenu() {
|
||||
const menuHtml = this.generateMenuHtml(MenuConfig);
|
||||
this.container.html(menuHtml);
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成菜单HTML(递归处理多级菜单)
|
||||
* @param {array} menuList - 菜单列表
|
||||
* @returns {string} - 菜单HTML
|
||||
*/
|
||||
generateMenuHtml(menuList) {
|
||||
let html = '<ul class="sidebar-menu">';
|
||||
|
||||
menuList.forEach(menu => {
|
||||
const hasChildren = menu.children && menu.children.length > 0;
|
||||
const isActive = window.location.pathname.includes(menu.url);
|
||||
|
||||
html += `<li class="menu-item ${hasChildren ? 'has-children' : ''} ${isActive ? 'active' : ''}" data-id="${menu.id}">`;
|
||||
|
||||
// 菜单标题
|
||||
html += `<div class="menu-title">`;
|
||||
html += `<span class="menu-icon">${menu.icon}</span>`;
|
||||
html += `<span class="menu-text">${menu.title}</span>`;
|
||||
if (hasChildren) {
|
||||
html += `<span class="menu-toggle ${this.collapse ? 'collapsed' : ''}">${this.collapse ? '+' : '-'}</span>`;
|
||||
}
|
||||
html += `</div>`;
|
||||
|
||||
// 子菜单
|
||||
if (hasChildren) {
|
||||
html += `<ul class="sub-menu ${this.collapse ? 'hidden' : ''}">`;
|
||||
html += this.generateMenuHtml(menu.children);
|
||||
html += `</ul>`;
|
||||
} else if (menu.url) {
|
||||
// 菜单项链接
|
||||
html += `<a href="${menu.url}" class="menu-link"></a>`;
|
||||
}
|
||||
|
||||
html += `</li>`;
|
||||
});
|
||||
|
||||
html += '</ul>';
|
||||
return html;
|
||||
},
|
||||
|
||||
/**
|
||||
* 绑定事件
|
||||
*/
|
||||
bindEvents() {
|
||||
// 菜单折叠/展开
|
||||
this.container.on('click', '.menu-toggle', (e) => {
|
||||
const $toggle = $(e.currentTarget);
|
||||
const $subMenu = $toggle.closest('.menu-item').find('.sub-menu');
|
||||
|
||||
this.collapse = !this.collapse;
|
||||
localStorage.setItem(SystemConfig.menuCollapseKey, this.collapse);
|
||||
|
||||
$toggle.text(this.collapse ? '+' : '-');
|
||||
$subMenu.toggleClass('hidden', this.collapse);
|
||||
this.updateCollapseState();
|
||||
});
|
||||
|
||||
// 菜单项点击(无链接时展开子菜单)
|
||||
this.container.on('click', '.menu-title:not(.has-children)', (e) => {
|
||||
const $title = $(e.currentTarget);
|
||||
const $link = $title.siblings('.menu-link');
|
||||
if ($link.length) {
|
||||
$link[0].click();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新折叠状态样式
|
||||
*/
|
||||
updateCollapseState() {
|
||||
$('.sidebar').toggleClass('collapsed', this.collapse);
|
||||
$('.main-content').toggleClass('sidebar-collapsed', this.collapse);
|
||||
}
|
||||
};
|
||||
|
||||
// 添加侧边栏样式
|
||||
$('head').append(`
|
||||
<style>
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
height: 100%;
|
||||
background-color: var(--bg-light-color);
|
||||
border-right: 1px solid var(--border-color);
|
||||
transition: width 0.3s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sidebar.collapsed {
|
||||
width: 60px;
|
||||
}
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
}
|
||||
.menu-item {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.menu-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
.menu-title:hover {
|
||||
background-color: var(--hover-color);
|
||||
}
|
||||
.menu-item.active .menu-title {
|
||||
background-color: var(--active-color);
|
||||
}
|
||||
.menu-icon {
|
||||
margin-right: 12px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.menu-text {
|
||||
flex: 1;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.sidebar.collapsed .menu-text {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.menu-toggle {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.sub-menu {
|
||||
list-style: none;
|
||||
background-color: var(--bg-color);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.sub-menu.hidden {
|
||||
display: none;
|
||||
}
|
||||
.menu-link {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
transition: margin-left 0.3s ease;
|
||||
}
|
||||
.main-content.sidebar-collapsed {
|
||||
margin-left: -180px;
|
||||
}
|
||||
</style>
|
||||
`);
|
||||
Reference in New Issue
Block a user