11<template >
22 <div class =" layout-columns" >
33 <div v-show =" isDesktop" class =" layout-columns__left" >
4- <div class =" layout-columns__menu-wrapper" >
5- <!-- 左侧一级菜单区域 -->
6- <OneLevelMenu :menus =" oneLevelMenus" @menu-click =" handleMenuClick" ></OneLevelMenu >
7- <div class =" layout-columns__right-menu" :class =" { collapsed: appStore.menuCollapse }" >
8- <!-- 系统标题 -->
9- <div class =" layout-columns__title" @click =" toHome" >
10- <span v-show =" !appStore.menuCollapse" class =" system-name gi_line_1" >{{ title }}</span >
11- </div >
12- <!-- 左侧二级菜单区域 -->
13- <Menu
14- v-if =" twoLevelMenus.length > 1" class =" layout-columns__menu" :menus =" twoLevelMenus"
15- :menu-style =" menuStyle"
16- />
17- </div >
4+ <!-- 左侧一级菜单区域 -->
5+ <OneLevelMenu :menus =" oneLevelMenus" @menu-click =" handleMenuItemClickByItem" ></OneLevelMenu >
6+
7+ <!-- 左侧二级菜单区域 -->
8+ <div class =" layout-columns__right-menu" >
9+ <div class =" layout-columns__system-name gi_line_1" >{{ appStore.getTitle() }}</div >
10+ <Menu
11+ v-if =" twoLevelMenus.length > 1 || oneLevelMenuActiveRoute?.meta?.alwaysShow === true"
12+ class =" layout-columns__menu" :menus =" twoLevelMenus" :menu-style =" { width: '180px' }"
13+ />
1814 </div >
1915 </div >
2016
2824</template >
2925
3026<script setup lang="ts">
31- import type { RouteRecordRaw } from ' vue-router'
32- import { findTree , mapTree } from ' xe-utils'
3327import Header from ' ./components/Header/index.vue'
3428import Main from ' ./components/Main.vue'
3529import Menu from ' ./components/Menu/index.vue'
3630import OneLevelMenu from ' ./components/OneLevelMenu/index.vue'
3731import Tabs from ' ./components/Tabs/index.vue'
38- import { filterTree } from ' @/utils '
39- import { useAppStore , useRouteStore } from ' @/stores '
32+ import { useAppStore } from ' @/stores '
33+ import { useLevelMenu } from ' @/layout/hooks/useLevelMenu '
4034import { useDevice } from ' @/hooks'
4135
4236defineOptions ({ name: ' LayoutColumns' })
4337
44- const route = useRoute ()
45- const router = useRouter ()
4638const appStore = useAppStore ()
47- const routeStore = useRouteStore ()
4839const { isDesktop } = useDevice ()
4940
50- // 系统标题和Logo
51- const title = computed (() => appStore .getTitle ())
52-
53- // 菜单样式 - 根据折叠状态动态调整宽度
54- const menuStyle = computed (() => {
55- return {
56- width: appStore .menuCollapse ? ' 48px' : ' 200px' ,
57- }
58- })
59-
60- // 跳转首页
61- const toHome = () => {
62- router .push (' /' )
63- }
64-
65- // 处理菜单路由数据
66- const cloneRoutes = JSON .parse (JSON .stringify (routeStore .routes )) as RouteRecordRaw []
67- const showMenuList = filterTree (cloneRoutes , (i ) => i .meta ?.hidden === false ) as RouteRecordRaw []
68-
69- // 一级菜单
70- const oneLevelMenus = ref <RouteRecordRaw []>([])
71- function getOneLevelMenus() {
72- const cloneList = JSON .parse (JSON .stringify (routeStore .routes )) as RouteRecordRaw []
73- const formatList = mapTree (cloneList , (i ) => {
74- if (i ?.children ?.length === 1 && i ?.meta ?.alwaysShow !== true ) {
75- return i .children ?.[0 ]
76- }
77- return i
78- })
79- const arr = formatList .filter ((i ) => i .meta ?.hidden === false )
80- return arr
81- }
82- oneLevelMenus .value = getOneLevelMenus ()
83-
84- // 二级菜单
85- const twoLevelMenus = computed (() => {
86- const obj = findTree (showMenuList , (i ) => i .path === route .path )
87- return showMenuList ?.[Number (obj .path [0 ])]?.children || []
88- })
89-
90- function handleMenuClick(item : RouteRecordRaw ) {
91- if (item .redirect === ' noRedirect' ) {
92- router .replace ({ path: item .children ?.[0 ]?.path })
93- return
94- }
95- router .replace ({ path: (item .redirect as string ) || item .path })
96- }
41+ const { oneLevelMenus, twoLevelMenus, oneLevelMenuActiveRoute, getOneLevelMenus, handleMenuItemClickByItem } = useLevelMenu ()
42+ getOneLevelMenus ()
9743 </script >
9844
9945<style lang="scss" scoped>
10046.layout-columns {
47+ display : flex ;
10148 width : 100% ;
10249 height : 100% ;
103- display : flex ;
10450 overflow : hidden ;
10551
10652 & __left {
107- height : 100% ;
108- background-color : var (--color-bg-1 );
109- overflow : hidden ;
110- display : flex ;
111- flex-direction : column ;
112- position : relative ;
113- }
114-
115- & __menu-wrapper {
116- flex : 1 ;
11753 display : flex ;
54+ height : 100% ;
11855 overflow : hidden ;
56+ background-color : var (--color-bg-1 );
11957 }
12058
12159 & __right-menu {
122- flex-shrink : 0 ;
12360 display : flex ;
12461 flex-direction : column ;
62+ width : 180px ;
12563 overflow : hidden ;
126- border-right : 1px solid var (--color-border-2 );
127- transition : width 0.2s ;
128- width : 200px ;
129-
130- & .collapsed {
131- width : 48px ;
132- }
64+ background-color : var (--color-bg-1 );
13365 }
13466
135- & __title {
67+ & __system-name {
13668 height : 56px ;
13769 padding : 0 12px ;
13870 color : var (--color-text-1 );
@@ -146,61 +78,22 @@ function handleMenuClick(item: RouteRecordRaw) {
14678 border-bottom : 1px solid var (--color-border );
14779 cursor : pointer ;
14880 user-select : none ;
149- transition : padding 0 .2s ;
81+ transition : padding .2s ;
15082
151- .layout-columns__right-menu.collapsed & {
152- padding : 0 ;
153- }
154-
155- .logo {
156- width : 32px ;
157- height : 32px ;
158- border-radius : 6px ;
159- transition : all 0.2s ;
160- overflow : hidden ;
161- flex-shrink : 0 ;
162- }
163-
164- .system-name {
165- padding-left : 6px ;
166- white-space : nowrap ;
167- transition : color 0.3s ;
168- line-height : 1.5 ;
169- display : inline-flex ;
170- align-items : center ;
171-
172- & :hover {
173- color : $color-theme !important ;
174- cursor : pointer ;
175- }
83+ & :hover {
84+ color : $color-theme !important ;
85+ cursor : pointer ;
17686 }
17787 }
178-
17988 & __menu {
18089 flex : 1 ;
181- overflow : hidden ;
182- }
183-
184- // 折叠状态下的菜单样式
185- :deep (.arco-menu.arco-menu-vertical.arco-menu-collapsed ) {
186- .arco- menu- icon {
187- margin-right : 0 ;
188- padding : 10px 0 ;
189- }
190-
191- .arco-menu-has-icon {
192- padding : 0 ;
193- justify-content : center ;
194- }
195-
196- .arco-menu-title {
197- display : none ;
198- }
90+ overflow : auto ;
91+ border-right : 1px solid var (--color-border-2 );
19992 }
20093
20194 & __content {
202- flex : 1 ;
20395 display : flex ;
96+ flex : 1 ;
20497 flex-direction : column ;
20598 overflow : hidden ;
20699 }
0 commit comments