feat(web): 允许收起左侧菜单以让出内容宽度。

顶栏提供收起按钮,收起后侧栏宽度为 0,不再保留被挤压的图标条。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-11-05 09:39:47 +08:00
1 parent 8e9536332a
commit 13cf2e216d
9 files changed
+63 -7

No files matched your search

+1 -1
View File
@@ -93,7 +93,7 @@
- **树形区**:一整棵业务菜单树,**只展示非叶子**(一级如「报销管理」「CRM管理」作为可展开目录;最后一层非叶子如「基础配置」可点击打开右侧组 Tab)。叶子不在侧栏展示。数字角标挂在组节点上(汇总可见叶子)。
- **内容区自上而下**:顶栏(面包屑/工具,高约 56px)→ **组叶子 Tab 条**(该组可见叶子多于 1 个时)→ 页面内容。单叶子组(如 CRM 产品管理、客户管理)不渲染 Tab 条。
- **仍默认不展示 WorkTab**(可关闭的历史页签)。组 Tab **不是** WorkTab:不能单个关闭;换最后一层非叶子则整组替换;默认只加载当前叶子,点哪个 Tab 再加载哪个页。
- **树区宽度**:约 `260px`。
- **树区宽度**:展开约 `260px`。顶栏左侧提供收起按钮:收起后侧栏宽度为 `0`,不保留图标条;再次点击展开。收起状态写入本地设置。
- **门户(PORTAL)/ 双列(DUAL_MENU)**:不再作为产品默认壳层。
- **色调**:Fresh Mint(`--primary #10b981` 链);不得使用案例 HTML 的 `#167c4a` 作为主色。
@@ -27,6 +27,9 @@
icon="fold"
class="ml-3 max-sm:ml-[7px] menu-fold-btn"
:class="{ 'is-menu-collapsed': !menuOpen }"
:title="menuOpen ? '收起菜单' : '展开菜单'"
:aria-label="menuOpen ? '收起菜单' : '展开菜单'"
:aria-expanded="menuOpen"
@click="visibleMenu"
/>
@@ -63,7 +63,7 @@
<div
v-show="menuList.length > 0"
class="menu-left"
:class="`menu-left-${getMenuTheme.theme} menu-left-${!menuOpen ? 'close' : 'open'}`"
:class="`menu-left-${getMenuTheme.theme} menu-left-${showIconRail ? 'close' : 'open'}`"
:style="{ background: getMenuTheme.background }"
>
<!-- 非双列:Logo + 系统名称(门户顶栏已展示则侧栏隐藏) -->
@@ -91,7 +91,7 @@
<ElScrollbar :style="scrollbarStyle">
<ElMenu
:class="'el-menu-' + getMenuTheme.theme"
:collapse="!menuOpen"
:collapse="showIconRail"
:default-active="routerPath"
:text-color="getMenuTheme.textColor"
:unique-opened="false"
@@ -181,6 +181,8 @@
menuType.value === MenuTypeEnum.PORTAL
)
const isDualMenu = computed(() => menuType.value === MenuTypeEnum.DUAL_MENU)
/** 单列侧栏收起时整栏隐藏;仅双列菜单仍使用图标窄栏 */
const showIconRail = computed(() => isDualMenu.value && !menuOpen.value)
// 移动端屏幕判断(使用 computed 避免重复计算)
const isMobileScreen = computed(() => width.value < MOBILE_BREAKPOINT)
@@ -306,6 +306,38 @@
box-shadow: none !important;
}
// 桌面收起:只留 Logo 与一级图标,名称由折叠菜单弹出层展示
.menu-left-close {
.header {
padding: 0 4px;
.header-brand-title {
display: none;
}
}
.el-menu.el-menu--collapse {
width: 100%;
padding-right: 4px;
padding-left: 4px;
> .el-menu-item,
> .el-sub-menu > .el-sub-menu__title {
justify-content: center;
padding-right: 0 !important;
padding-left: 0 !important;
}
.menu-icon {
margin: 0 !important;
}
.el-sub-menu__icon-arrow {
display: none;
}
}
}
.el-menu {
box-sizing: border-box;
// 防止菜单内的滚动影响整个页面滚动
+1 -1
View File
@@ -15,7 +15,7 @@ import { HeaderBarFeatureConfig } from '@/types'
*/
export const headerBarConfig: HeaderBarFeatureConfig = {
menuButton: {
enabled: false,
enabled: true,
description: '控制左侧菜单的展开/收起按钮'
},
refreshButton: {
+2 -2
View File
@@ -43,8 +43,8 @@ export const SETTING_DEFAULT_CONFIG = {
menuThemeType: MenuThemeEnum.DESIGN,
/** 系统主题颜色 */
systemThemeColor: AppConfig.systemMainColor[0],
/** 是否显示菜单按钮 */
showMenuButton: false,
/** 是否显示菜单按钮(顶栏收起/展开侧栏) */
showMenuButton: true,
/** 是否显示快速入口 */
showFastEnter: true,
/** 是否显示刷新按钮 */
+4
View File
@@ -458,6 +458,10 @@ export const useSettingStore = defineStore(
} else if (width === 290) {
ctx.store.setMenuOpenWidth(270)
}
// 旧本地配置把收起按钮关掉了;产品需要顶栏始终能收起侧栏
if (!ctx.store.showMenuButton) {
ctx.store.setButton()
}
}
}
}
+6
View File
@@ -81,4 +81,10 @@
<style lang="scss" scoped>
@use './style' as layout-base;
@use './style.portal' as layout-portal;
/* 内层保持展开宽度,收起时由外层裁切,避免菜单被挤成图标条 */
#app-sidebar :deep(.layout-sidebar) {
width: var(--app-sidebar-open-width, 260px);
min-width: var(--app-sidebar-open-width, 260px);
}
</style>
+10 -1
View File
@@ -9,6 +9,8 @@
flex-shrink: 0;
width: var(--app-sidebar-open-width, 260px);
height: 100vh;
overflow: hidden;
transition: width 0.2s ease;
border-right: 1px solid var(--mint-border, #d9e8e2);
background: var(--mint-surface, #fff);
box-sizing: border-box;
@@ -27,7 +29,14 @@
}
&.is-collapsed {
width: var(--app-sidebar-close-width, 64px);
width: 0;
min-width: 0;
border-right-width: 0;
pointer-events: none;
&::after {
content: none;
}
}
}