vben
authored
|
1
2
|
import './index.less';
|
vben
authored
|
3
|
import type { PropType, CSSProperties } from 'vue';
|
|
4
|
|
vben
authored
|
5
|
import { computed, defineComponent, unref, toRef } from 'vue';
|
vben
authored
|
6
|
import { BasicMenu } from '/@/components/Menu';
|
vben
authored
|
7
8
9
10
11
|
import { AppLogo } from '/@/components/Application';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
vben
authored
|
12
|
import { ScrollContainer } from '/@/components/Container';
|
vben
authored
|
13
14
15
16
|
import { useGo } from '/@/hooks/web/usePage';
import { useSplitMenu } from './useLayoutMenu';
import { openWindow } from '/@/utils';
|
vben
authored
|
17
|
import { propTypes } from '/@/utils/propTypes';
|
vben
authored
|
18
19
|
import { isUrl } from '/@/utils/is';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
vben
authored
|
20
21
|
import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '/@/hooks/web/useDesign';
|
|
22
23
|
export default defineComponent({
|
vben
authored
|
24
|
name: 'LayoutMenu',
|
|
25
|
props: {
|
vben
authored
|
26
27
|
theme: propTypes.oneOf(['light', 'dark']),
|
|
28
29
30
31
|
splitType: {
type: Number as PropType<MenuSplitTyeEnum>,
default: MenuSplitTyeEnum.NONE,
},
|
vben
authored
|
32
33
34
|
isHorizontal: propTypes.bool,
// menu Mode
|
|
35
|
menuMode: {
|
vben
authored
|
36
|
type: [String] as PropType<Nullable<MenuModeEnum>>,
|
|
37
38
39
40
|
default: '',
},
},
setup(props) {
|
vben
authored
|
41
|
const go = useGo();
|
|
42
|
|
vben
authored
|
43
|
const {
|
vben
authored
|
44
45
46
|
getMenuMode,
getMenuType,
getMenuTheme,
|
vben
authored
|
47
|
getCollapsed,
|
vben
authored
|
48
|
getCollapsedShowTitle,
|
vben
authored
|
49
|
getAccordion,
|
vben
authored
|
50
|
getIsHorizontal,
|
vben
authored
|
51
|
getIsSidebarType,
|
vben
authored
|
52
53
|
} = useMenuSetting();
const { getShowLogo } = useRootSetting();
|
vben
authored
|
54
|
|
vben
authored
|
55
56
|
const { prefixCls } = useDesign('layout-menu');
|
vben
authored
|
57
|
const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
|
|
58
|
|
vben
authored
|
59
60
61
62
63
|
const { getIsMobile } = useAppInject();
const getComputedMenuMode = computed(() =>
unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)
);
|
|
64
|
|
vben
authored
|
65
|
const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
|
vben
authored
|
66
67
68
69
|
const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
const getUseScroll = computed(() => {
|
vben
authored
|
70
71
72
73
74
75
|
return (
!unref(getIsHorizontal) &&
(unref(getIsSidebarType) ||
props.splitType === MenuSplitTyeEnum.LEFT ||
props.splitType === MenuSplitTyeEnum.NONE)
);
|
vben
authored
|
76
77
78
79
80
81
82
83
84
|
});
const getWrapperStyle = computed(
(): CSSProperties => {
return {
height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
};
}
);
|
vben
authored
|
85
86
87
88
89
90
91
92
93
94
|
const getLogoClass = computed(() => {
return [
`${prefixCls}-logo`,
unref(getComputedMenuTheme),
{
[`${prefixCls}--mobile`]: unref(getIsMobile),
},
];
});
|
vben
authored
|
95
96
97
98
|
/**
* click menu
* @param menu
*/
|
vben
authored
|
99
|
|
vben
authored
|
100
101
|
function handleMenuClick(path: string) {
go(path);
|
|
102
103
|
}
|
vben
authored
|
104
105
106
107
|
/**
* before click menu
* @param menu
*/
|
vben
authored
|
108
109
110
|
async function beforeMenuClickFn(path: string) {
if (!isUrl(path)) {
return true;
|
|
111
|
}
|
vben
authored
|
112
113
|
openWindow(path);
return false;
|
|
114
115
|
}
|
vben
authored
|
116
|
function renderHeader() {
|
vben
authored
|
117
|
if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
|
vben
authored
|
118
|
|
|
119
|
return (
|
vben
authored
|
120
121
|
<AppLogo
showTitle={!unref(getCollapsed)}
|
vben
authored
|
122
|
class={unref(getLogoClass)}
|
vben
authored
|
123
|
theme={unref(getComputedMenuTheme)}
|
vben
authored
|
124
|
/>
|
|
125
|
);
|
vben
authored
|
126
|
}
|
vben
authored
|
127
|
|
vben
authored
|
128
|
function renderMenu() {
|
|
129
130
|
return (
<BasicMenu
|
vben
authored
|
131
132
|
beforeClickFn={beforeMenuClickFn}
isHorizontal={props.isHorizontal}
|
vben
authored
|
133
|
type={unref(getMenuType)}
|
vben
authored
|
134
135
|
collapsedShowTitle={unref(getCollapsedShowTitle)}
showLogo={unref(getIsShowLogo)}
|
vben
authored
|
136
137
|
mode={unref(getComputedMenuMode)}
theme={unref(getComputedMenuTheme)}
|
|
138
|
items={unref(menusRef)}
|
vben
authored
|
139
140
|
accordion={unref(getAccordion)}
onMenuClick={handleMenuClick}
|
vben
authored
|
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
/>
);
}
return () => {
return (
<>
{renderHeader()}
{unref(getUseScroll) ? (
<ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer>
) : (
renderMenu()
)}
</>
|
|
155
156
157
158
|
);
};
},
});
|