鞍钢鲅鱼圈能源管控系统前端代码
houzhongjian
2024-12-26 cb6cd26221d8bb2c4b1dca44a87332e9fe6f56ab
提交 | 用户 | 时间
cb6cd2 1 <script lang="tsx">
H 2 import { PropType } from 'vue'
3 import { ElMenu, ElScrollbar } from 'element-plus'
4 import { useAppStore } from '@/store/modules/app'
5 import { usePermissionStore } from '@/store/modules/permission'
6 import { useRenderMenuItem } from './components/useRenderMenuItem'
7 import { isUrl } from '@/utils/is'
8 import { useDesign } from '@/hooks/web/useDesign'
9 import { LayoutType } from '@/types/layout'
10
11 const { getPrefixCls } = useDesign()
12
13 const prefixCls = getPrefixCls('menu')
14
15 export default defineComponent({
16   // eslint-disable-next-line vue/no-reserved-component-names
17   name: 'Menu',
18   props: {
19     menuSelect: {
20       type: Function as PropType<(index: string) => void>,
21       default: undefined
22     }
23   },
24   setup(props) {
25     const appStore = useAppStore()
26
27     const layout = computed(() => appStore.getLayout)
28
29     const { push, currentRoute } = useRouter()
30
31     const permissionStore = usePermissionStore()
32
33     const menuMode = computed((): 'vertical' | 'horizontal' => {
34       // 竖
35       const vertical: LayoutType[] = ['classic', 'topLeft', 'cutMenu']
36
37       if (vertical.includes(unref(layout))) {
38         return 'vertical'
39       } else {
40         return 'horizontal'
41       }
42     })
43
44     const routers = computed(() =>
45       unref(layout) === 'cutMenu' ? permissionStore.getMenuTabRouters : permissionStore.getRouters
46     )
47
48     const collapse = computed(() => appStore.getCollapse)
49
50     const uniqueOpened = computed(() => appStore.getUniqueOpened)
51
52     const activeMenu = computed(() => {
53       const { meta, path } = unref(currentRoute)
54       // if set path, the sidebar will highlight the path you set
55       if (meta.activeMenu) {
56         return meta.activeMenu as string
57       }
58       return path
59     })
60
61     const menuSelect = (index: string) => {
62       if (props.menuSelect) {
63         props.menuSelect(index)
64       }
65       // 自定义事件
66       if (isUrl(index)) {
67         window.open(index)
68       } else {
69         push(index)
70       }
71     }
72
73     const renderMenuWrap = () => {
74       if (unref(layout) === 'top') {
75         return renderMenu()
76       } else {
77         return <ElScrollbar>{renderMenu()}</ElScrollbar>
78       }
79     }
80
81     const renderMenu = () => {
82       return (
83         <ElMenu
84           defaultActive={unref(activeMenu)}
85           mode={unref(menuMode)}
86           collapse={
87             unref(layout) === 'top' || unref(layout) === 'cutMenu' ? false : unref(collapse)
88           }
89           uniqueOpened={unref(layout) === 'top' ? false : unref(uniqueOpened)}
90           backgroundColor="var(--left-menu-bg-color)"
91           textColor="var(--left-menu-text-color)"
92           activeTextColor="var(--left-menu-text-active-color)"
93           onSelect={menuSelect}
94         >
95           {{
96             default: () => {
97               const { renderMenuItem } = useRenderMenuItem(unref(menuMode))
98               return renderMenuItem(unref(routers))
99             }
100           }}
101         </ElMenu>
102       )
103     }
104
105     return () => (
106       <div
107         id={prefixCls}
108         class={[
109           `${prefixCls} ${prefixCls}__${unref(menuMode)}`,
110           'h-[100%] overflow-hidden flex-col bg-[var(--left-menu-bg-color)]',
111           {
112             'w-[var(--left-menu-min-width)]': unref(collapse) && unref(layout) !== 'cutMenu',
113             'w-[var(--left-menu-max-width)]': !unref(collapse) && unref(layout) !== 'cutMenu'
114           }
115         ]}
116       >
117         {renderMenuWrap()}
118       </div>
119     )
120   }
121 })
122 </script>
123
124 <style lang="scss" scoped>
125 $prefix-cls: #{$namespace}-menu;
126
127 .#{$prefix-cls} {
128   position: relative;
129   transition: width var(--transition-time-02);
130
131   :deep(.#{$elNamespace}-menu) {
132     width: 100% !important;
133     border-right: none;
134
135     // 设置选中时子标题的颜色
136     .is-active {
137       & > .#{$elNamespace}-sub-menu__title {
138         color: var(--left-menu-text-active-color) !important;
139       }
140     }
141
142     // 设置子菜单悬停的高亮和背景色
143     .#{$elNamespace}-sub-menu__title,
144     .#{$elNamespace}-menu-item {
145       &:hover {
146         color: var(--left-menu-text-active-color) !important;
147         background-color: var(--left-menu-bg-color) !important;
148       }
149     }
150
151     // 设置选中时的高亮背景和高亮颜色
152     .#{$elNamespace}-menu-item.is-active {
153       color: var(--left-menu-text-active-color) !important;
154       background-color: var(--left-menu-bg-active-color) !important;
155
156       &:hover {
157         background-color: var(--left-menu-bg-active-color) !important;
158       }
159     }
160
161     .#{$elNamespace}-menu-item.is-active {
162       position: relative;
163     }
164
165     // 设置子菜单的背景颜色
166     .#{$elNamespace}-menu {
167       .#{$elNamespace}-sub-menu__title,
168       .#{$elNamespace}-menu-item:not(.is-active) {
169         background-color: var(--left-menu-bg-light-color) !important;
170       }
171     }
172   }
173
174   // 折叠时的最小宽度
175   :deep(.#{$elNamespace}-menu--collapse) {
176     width: var(--left-menu-min-width);
177
178     & > .is-active,
179     & > .is-active > .#{$elNamespace}-sub-menu__title {
180       position: relative;
181       background-color: var(--left-menu-collapse-bg-active-color) !important;
182     }
183   }
184
185   // 折叠动画的时候,就需要把文字给隐藏掉
186   :deep(.horizontal-collapse-transition) {
187     // transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out !important;
188     .#{$prefix-cls}__title {
189       display: none;
190     }
191   }
192
193   // 水平菜单
194   &__horizontal {
195     height: calc(var(--top-tool-height)) !important;
196
197     :deep(.#{$elNamespace}-menu--horizontal) {
198       height: calc(var(--top-tool-height));
199       border-bottom: none;
200       // 重新设置底部高亮颜色
201       & > .#{$elNamespace}-sub-menu.is-active {
202         .#{$elNamespace}-sub-menu__title {
203           border-bottom-color: var(--el-color-primary) !important;
204         }
205       }
206
207       .#{$elNamespace}-menu-item.is-active {
208         position: relative;
209
210         &::after {
211           display: none !important;
212         }
213       }
214
215       .#{$prefix-cls}__title {
216         /* stylelint-disable-next-line */
217         max-height: calc(var(--top-tool-height) - 2px) !important;
218         /* stylelint-disable-next-line */
219         line-height: calc(var(--top-tool-height) - 2px);
220       }
221     }
222   }
223 }
224 </style>
225
226 <style lang="scss">
227 $prefix-cls: #{$namespace}-menu-popper;
228
229 .#{$prefix-cls}--vertical,
230 .#{$prefix-cls}--horizontal {
231   // 设置选中时子标题的颜色
232   .is-active {
233     & > .el-sub-menu__title {
234       color: var(--left-menu-text-active-color) !important;
235     }
236   }
237
238   // 设置子菜单悬停的高亮和背景色
239   .el-sub-menu__title,
240   .el-menu-item {
241     &:hover {
242       color: var(--left-menu-text-active-color) !important;
243       background-color: var(--left-menu-bg-color) !important;
244     }
245   }
246
247   // 设置选中时的高亮背景
248   .el-menu-item.is-active {
249     position: relative;
250     background-color: var(--left-menu-bg-active-color) !important;
251
252     &:hover {
253       background-color: var(--left-menu-bg-active-color) !important;
254     }
255   }
256 }
257 </style>