From 3f357215392745bb09f223d904577135c20b741c Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Wed, 13 Aug 2025 16:21:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/main-sidebar-hover.vue | 108 +++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 35 deletions(-) diff --git a/src/views/main-sidebar-hover.vue b/src/views/main-sidebar-hover.vue index 581be5f..4649b0e 100644 --- a/src/views/main-sidebar-hover.vue +++ b/src/views/main-sidebar-hover.vue @@ -26,9 +26,8 @@ v-for="menu in menuList" :key="menu.menuId" class="main-menu-item" - @mouseenter="showSubMenu(menu, $event)" - @mouseleave="hideSubMenu" - @click="handleMainMenuClick(menu)"> + :class="{ 'active': hoveredMenu && hoveredMenu.menuId === menu.menuId }" + @click="handleMainMenuClick(menu, $event)"> {{ menu.name }} @@ -39,9 +38,8 @@ v-for="menu in favoriteList" :key="'fav-' + menu.menuId" class="main-menu-item favorite-menu" - @mouseenter="showSubMenu(menu, $event)" - @mouseleave="hideSubMenu" - @click="handleMainMenuClick(menu)"> + :class="{ 'active': hoveredMenu && hoveredMenu.menuId === menu.menuId }" + @click="handleMainMenuClick(menu, $event)"> {{ menu.name }} @@ -62,9 +60,8 @@ v-for="menu in menuList" :key="menu.menuId" class="main-menu-item folded-item" - @mouseenter="showSubMenu(menu, $event)" - @mouseleave="hideSubMenu" - @click="handleMainMenuClick(menu)" + :class="{ 'active': hoveredMenu && hoveredMenu.menuId === menu.menuId }" + @click="handleMainMenuClick(menu, $event)" :title="menu.name"> @@ -74,9 +71,8 @@ v-for="menu in favoriteList" :key="'fav-' + menu.menuId" class="main-menu-item folded-item favorite-menu" - @mouseenter="showSubMenu(menu, $event)" - @mouseleave="hideSubMenu" - @click="handleMainMenuClick(menu)" + :class="{ 'active': hoveredMenu && hoveredMenu.menuId === menu.menuId }" + @click="handleMainMenuClick(menu, $event)" :title="menu.name"> @@ -89,8 +85,7 @@ v-if="hoveredMenu && hoveredMenu.list && hoveredMenu.list.length > 0" class="hover-submenu" :style="submenuStyle" - @mouseenter="keepSubMenuVisible" - @mouseleave="hideSubMenu"> + @click.stop> @@ -130,7 +125,7 @@ @@ -218,6 +213,14 @@ export default { this.routeHandle(this.$route) this.getFunctionButtonList() }, + mounted() { + // 添加全局点击监听,点击其他地方时收起菜单 + document.addEventListener('click', this.handleDocumentClick) + }, + beforeDestroy() { + // 移除全局点击监听 + document.removeEventListener('click', this.handleDocumentClick) + }, methods: { // 获取页面多语言数据 getFunctionButtonList() { @@ -249,11 +252,6 @@ export default { // 显示子菜单 showSubMenu(menu, event) { - if (this.hideTimer) { - clearTimeout(this.hideTimer) - this.hideTimer = null - } - if (menu.list && menu.list.length > 0) { this.hoveredMenu = menu const rect = event.currentTarget.getBoundingClientRect() @@ -267,24 +265,42 @@ export default { // 隐藏子菜单 hideSubMenu() { - this.hideTimer = setTimeout(() => { - this.hoveredMenu = null - this.submenuStyle = { display: 'none' } - }, 100) + this.hoveredMenu = null + this.submenuStyle = { display: 'none' } }, - // 保持子菜单可见 - keepSubMenuVisible() { - if (this.hideTimer) { - clearTimeout(this.hideTimer) - this.hideTimer = null + // 处理主菜单点击 + handleMainMenuClick(menu, event) { + // 阻止事件冒泡,避免触发全局点击事件 + if (event) { + event.stopPropagation() + } + + // 如果菜单有子菜单 + if (menu.list && menu.list.length > 0) { + // 如果当前菜单已经展开,则收起 + if (this.hoveredMenu && this.hoveredMenu.menuId === menu.menuId) { + this.hideSubMenu() + } else { + // 否则展开当前菜单 + this.showSubMenu(menu, event || window.event) + } + } else { + // 如果没有子菜单,直接跳转 + this.gotoRouteHandle(menu) + this.hideSubMenu() // 跳转后收起任何已展开的菜单 } }, - // 处理主菜单点击 - handleMainMenuClick(menu) { - if (!menu.list || menu.list.length === 0) { - this.gotoRouteHandle(menu) + // 处理全局点击事件 + handleDocumentClick(event) { + // 检查点击是否在侧边栏或子菜单内 + const sidebar = this.$el + const submenu = document.querySelector('.hover-submenu') + + if (sidebar && !sidebar.contains(event.target) && + (!submenu || !submenu.contains(event.target))) { + this.hideSubMenu() } }, @@ -620,6 +636,28 @@ export default { &:hover .sidebar-menu-icon { transform: scale(1.1); } + + // 活跃状态样式 + &.active { + background: linear-gradient(135deg, rgba(23, 179, 163, 0.2), rgba(11, 178, 212, 0.2)); + color: #fff; + transform: translateX(5px); + + &::before { + width: 4px; + } + + .menu-arrow { + transform: translateX(5px) rotate(90deg); + opacity: 1; + color: #fff; + } + + .sidebar-menu-icon { + transform: scale(1.1); + color: #17B3A3; + } + } } } }