Commit 88f4a3f02a0c0f35953c93427fe700d414b6ec50
1 parent
74e62cbc
perf: perf menu
Showing
24 changed files
with
557 additions
and
579 deletions
src/components/Application/src/AppLocalePicker.vue
@@ -8,10 +8,10 @@ | @@ -8,10 +8,10 @@ | ||
8 | :dropMenuList="localeList" | 8 | :dropMenuList="localeList" |
9 | :selectedKeys="selectedKeys" | 9 | :selectedKeys="selectedKeys" |
10 | @menuEvent="handleMenuEvent" | 10 | @menuEvent="handleMenuEvent" |
11 | - overlayClassName="app-locale-picker-overlay" | 11 | + :overlayClassName="`${prefixCls}-overlay`" |
12 | > | 12 | > |
13 | - <span class="app-local-picker"> | ||
14 | - <GlobalOutlined class="app-local-picker__icon" /> | 13 | + <span :class="prefixCls"> |
14 | + <GlobalOutlined :class="`${prefixCls}__icon`" /> | ||
15 | <span v-if="showText">{{ getLangText }}</span> | 15 | <span v-if="showText">{{ getLangText }}</span> |
16 | </span> | 16 | </span> |
17 | </Dropdown> | 17 | </Dropdown> |
@@ -28,6 +28,7 @@ | @@ -28,6 +28,7 @@ | ||
28 | import { LocaleType } from '/@/locales/types'; | 28 | import { LocaleType } from '/@/locales/types'; |
29 | 29 | ||
30 | import { propTypes } from '/@/utils/propTypes'; | 30 | import { propTypes } from '/@/utils/propTypes'; |
31 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
31 | 32 | ||
32 | export default defineComponent({ | 33 | export default defineComponent({ |
33 | name: 'AppLocalPicker', | 34 | name: 'AppLocalPicker', |
@@ -39,9 +40,12 @@ | @@ -39,9 +40,12 @@ | ||
39 | reload: propTypes.bool, | 40 | reload: propTypes.bool, |
40 | }, | 41 | }, |
41 | setup(props) { | 42 | setup(props) { |
42 | - const { localeList } = useLocaleSetting(); | ||
43 | const selectedKeys = ref<string[]>([]); | 43 | const selectedKeys = ref<string[]>([]); |
44 | 44 | ||
45 | + const { prefixCls } = useDesign('app-locale-picker'); | ||
46 | + | ||
47 | + const { localeList } = useLocaleSetting(); | ||
48 | + | ||
45 | const { changeLocale, getLang } = useLocale(); | 49 | const { changeLocale, getLang } = useLocale(); |
46 | 50 | ||
47 | const getLangText = computed(() => { | 51 | const getLangText = computed(() => { |
@@ -64,19 +68,22 @@ | @@ -64,19 +68,22 @@ | ||
64 | toggleLocale(menu.event as string); | 68 | toggleLocale(menu.event as string); |
65 | } | 69 | } |
66 | 70 | ||
67 | - return { localeList, handleMenuEvent, selectedKeys, getLangText }; | 71 | + return { localeList, handleMenuEvent, selectedKeys, getLangText, prefixCls }; |
68 | }, | 72 | }, |
69 | }); | 73 | }); |
70 | </script> | 74 | </script> |
71 | 75 | ||
72 | <style lang="less" scoped> | 76 | <style lang="less" scoped> |
73 | - :global(.app-locale-picker-overlay) { | 77 | + @import (reference) '../../../design/index.less'; |
78 | + @prefix-cls: ~'@{namespace}-app-locale-picker'; | ||
79 | + | ||
80 | + :global(.@{prefix-cls}-overlay) { | ||
74 | .ant-dropdown-menu-item { | 81 | .ant-dropdown-menu-item { |
75 | min-width: 160px; | 82 | min-width: 160px; |
76 | } | 83 | } |
77 | } | 84 | } |
78 | 85 | ||
79 | - .app-local-picker { | 86 | + .@{prefix-cls} { |
80 | display: flex; | 87 | display: flex; |
81 | align-items: center; | 88 | align-items: center; |
82 | cursor: pointer; | 89 | cursor: pointer; |
src/components/Basic/src/BasicArrow.vue
@@ -20,15 +20,17 @@ | @@ -20,15 +20,17 @@ | ||
20 | expand: propTypes.bool, | 20 | expand: propTypes.bool, |
21 | top: propTypes.bool, | 21 | top: propTypes.bool, |
22 | bottom: propTypes.bool, | 22 | bottom: propTypes.bool, |
23 | + inset: propTypes.bool, | ||
23 | }, | 24 | }, |
24 | setup(props) { | 25 | setup(props) { |
25 | const getClass = computed(() => { | 26 | const getClass = computed(() => { |
26 | - const { expand, top, bottom } = props; | 27 | + const { expand, top, bottom, inset } = props; |
27 | return [ | 28 | return [ |
28 | 'base-arrow', | 29 | 'base-arrow', |
29 | { | 30 | { |
30 | 'base-arrow__active': expand, | 31 | 'base-arrow__active': expand, |
31 | top, | 32 | top, |
33 | + inset, | ||
32 | bottom, | 34 | bottom, |
33 | }, | 35 | }, |
34 | ]; | 36 | ]; |
@@ -47,6 +49,10 @@ | @@ -47,6 +49,10 @@ | ||
47 | transition: all 0.3s ease 0.1s; | 49 | transition: all 0.3s ease 0.1s; |
48 | transform-origin: center center; | 50 | transform-origin: center center; |
49 | 51 | ||
52 | + &.inset { | ||
53 | + line-height: 0px; | ||
54 | + } | ||
55 | + | ||
50 | &__active { | 56 | &__active { |
51 | transform: rotate(90deg); | 57 | transform: rotate(90deg); |
52 | } | 58 | } |
src/components/Menu/src/BasicMenu.tsx
@@ -9,14 +9,15 @@ import { | @@ -9,14 +9,15 @@ import { | ||
9 | unref, | 9 | unref, |
10 | reactive, | 10 | reactive, |
11 | watch, | 11 | watch, |
12 | - onMounted, | ||
13 | - ref, | ||
14 | toRefs, | 12 | toRefs, |
15 | ComputedRef, | 13 | ComputedRef, |
14 | + ref, | ||
15 | + CSSProperties, | ||
16 | } from 'vue'; | 16 | } from 'vue'; |
17 | import { Menu } from 'ant-design-vue'; | 17 | import { Menu } from 'ant-design-vue'; |
18 | import MenuContent from './MenuContent'; | 18 | import MenuContent from './MenuContent'; |
19 | // import { ScrollContainer } from '/@/components/Container'; | 19 | // import { ScrollContainer } from '/@/components/Container'; |
20 | +// import { BasicArrow } from '/@/components/Basic'; | ||
20 | 21 | ||
21 | import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; | 22 | import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; |
22 | import { ThemeEnum } from '/@/enums/appEnum'; | 23 | import { ThemeEnum } from '/@/enums/appEnum'; |
@@ -29,18 +30,20 @@ import { useRouter } from 'vue-router'; | @@ -29,18 +30,20 @@ import { useRouter } from 'vue-router'; | ||
29 | import { isFunction } from '/@/utils/is'; | 30 | import { isFunction } from '/@/utils/is'; |
30 | import { getSlot } from '/@/utils/helper/tsxHelper'; | 31 | import { getSlot } from '/@/utils/helper/tsxHelper'; |
31 | import { menuHasChildren } from './helper'; | 32 | import { menuHasChildren } from './helper'; |
32 | - | ||
33 | import { getCurrentParentPath } from '/@/router/menus'; | 33 | import { getCurrentParentPath } from '/@/router/menus'; |
34 | 34 | ||
35 | import { basicProps } from './props'; | 35 | import { basicProps } from './props'; |
36 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 36 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
37 | import { REDIRECT_NAME } from '/@/router/constant'; | 37 | import { REDIRECT_NAME } from '/@/router/constant'; |
38 | +import { tabStore } from '/@/store/modules/tab'; | ||
39 | +import { useDesign } from '/@/hooks/web/useDesign'; | ||
38 | export default defineComponent({ | 40 | export default defineComponent({ |
39 | name: 'BasicMenu', | 41 | name: 'BasicMenu', |
40 | props: basicProps, | 42 | props: basicProps, |
41 | emits: ['menuClick'], | 43 | emits: ['menuClick'], |
42 | setup(props, { slots, emit }) { | 44 | setup(props, { slots, emit }) { |
43 | const currentParentPath = ref(''); | 45 | const currentParentPath = ref(''); |
46 | + const isClickGo = ref(false); | ||
44 | 47 | ||
45 | const menuState = reactive<MenuState>({ | 48 | const menuState = reactive<MenuState>({ |
46 | defaultSelectedKeys: [], | 49 | defaultSelectedKeys: [], |
@@ -51,170 +54,184 @@ export default defineComponent({ | @@ -51,170 +54,184 @@ export default defineComponent({ | ||
51 | collapsedOpenKeys: [], | 54 | collapsedOpenKeys: [], |
52 | }); | 55 | }); |
53 | 56 | ||
54 | - const { getCollapsed } = useMenuSetting(); | 57 | + const { prefixCls } = useDesign('basic-menu'); |
55 | 58 | ||
56 | - const { currentRoute } = useRouter(); | 59 | + const { items, mode, accordion } = toRefs(props); |
60 | + | ||
61 | + const { getCollapsed, getIsHorizontal, getTopMenuAlign, getSplit } = useMenuSetting(); | ||
57 | 62 | ||
58 | - const { items, flatItems, mode, accordion } = toRefs(props); | 63 | + const { currentRoute } = useRouter(); |
59 | 64 | ||
60 | - const { handleOpenChange, resetKeys, setOpenKeys } = useOpenKeys( | 65 | + const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys( |
61 | menuState, | 66 | menuState, |
62 | items, | 67 | items, |
63 | - flatItems, | ||
64 | mode, | 68 | mode, |
65 | accordion | 69 | accordion |
66 | ); | 70 | ); |
67 | 71 | ||
68 | - const getOpenKeys = computed(() => { | ||
69 | - return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys; | 72 | + const getMenuClass = computed(() => { |
73 | + const { type } = props; | ||
74 | + const { mode } = menuState; | ||
75 | + return [ | ||
76 | + prefixCls, | ||
77 | + `justify-${unref(getTopMenuAlign)}`, | ||
78 | + { | ||
79 | + [`${prefixCls}--hide-title`]: !unref(showTitle), | ||
80 | + [`${prefixCls}--collapsed-show-title`]: props.collapsedShowTitle, | ||
81 | + [`${prefixCls}__second`]: | ||
82 | + !props.isHorizontal && appStore.getProjectConfig.menuSetting.split, | ||
83 | + [`${prefixCls}__sidebar-hor`]: | ||
84 | + type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL, | ||
85 | + }, | ||
86 | + ]; | ||
70 | }); | 87 | }); |
71 | 88 | ||
72 | - // menuๅคๅฑๆ ทๅผ | ||
73 | - const getMenuWrapStyle = computed((): any => { | ||
74 | - const { showLogo } = props; | ||
75 | - let offset = 0; | ||
76 | - | ||
77 | - if (showLogo) { | ||
78 | - offset += 46; | ||
79 | - } | ||
80 | - return { | ||
81 | - height: `calc(100% - ${offset}px)`, | ||
82 | - position: 'relative', | ||
83 | - overflowY: 'auto', | ||
84 | - }; | ||
85 | - }); | 89 | + const showTitle = computed(() => props.collapsedShowTitle && unref(getCollapsed)); |
86 | 90 | ||
87 | - // ๆฏๅฆ้ๆๅๅทฆไพงไธ็บง่ๅ | ||
88 | - const transparentMenuClass = computed(() => { | ||
89 | - const { type } = props; | ||
90 | - const { mode } = menuState; | ||
91 | - const cls: string[] = []; | ||
92 | - if ( | ||
93 | - (type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL) || | ||
94 | - props.appendClass | ||
95 | - ) { | ||
96 | - cls.push('basic-menu__sidebar-hor'); | ||
97 | - } | 91 | + const getInlineCollapseOptions = computed(() => { |
92 | + const isInline = props.mode === MenuModeEnum.INLINE; | ||
98 | 93 | ||
99 | - if (!props.isHorizontal && appStore.getProjectConfig.menuSetting.split) { | ||
100 | - cls.push('basic-menu__second'); | 94 | + const inlineCollapseOptions: { inlineCollapsed?: boolean } = {}; |
95 | + if (isInline) { | ||
96 | + inlineCollapseOptions.inlineCollapsed = unref(getCollapsed); | ||
101 | } | 97 | } |
102 | - return cls; | 98 | + return inlineCollapseOptions; |
103 | }); | 99 | }); |
104 | 100 | ||
105 | - const showTitle = computed(() => props.collapsedShowTitle && unref(getCollapsed)); | 101 | + const getWrapperStyle = computed( |
102 | + (): CSSProperties => { | ||
103 | + const isHorizontal = unref(getIsHorizontal); | ||
104 | + return { | ||
105 | + height: isHorizontal | ||
106 | + ? `calc(100% + 1px)` | ||
107 | + : `calc(100% - ${props.showLogo ? '48px' : '0'})`, | ||
108 | + overflowY: isHorizontal ? 'hidden' : 'auto', | ||
109 | + }; | ||
110 | + } | ||
111 | + ); | ||
106 | 112 | ||
107 | watch( | 113 | watch( |
108 | - () => currentRoute.value.name, | ||
109 | - (name: string) => { | ||
110 | - if (name === REDIRECT_NAME) return; | 114 | + () => tabStore.getCurrentTab, |
115 | + () => { | ||
116 | + if (unref(currentRoute).name === REDIRECT_NAME) return; | ||
111 | handleMenuChange(); | 117 | handleMenuChange(); |
112 | - props.isHorizontal && appStore.getProjectConfig.menuSetting.split && getParentPath(); | 118 | + unref(getSplit) && getParentPath(); |
113 | } | 119 | } |
114 | ); | 120 | ); |
115 | 121 | ||
116 | watch( | 122 | watch( |
117 | () => props.items, | 123 | () => props.items, |
118 | () => { | 124 | () => { |
119 | - if (props.items) { | ||
120 | - handleMenuChange(); | ||
121 | - } | 125 | + handleMenuChange(); |
122 | }, | 126 | }, |
123 | { | 127 | { |
124 | immediate: true, | 128 | immediate: true, |
125 | } | 129 | } |
126 | ); | 130 | ); |
127 | 131 | ||
132 | + getParentPath(); | ||
133 | + | ||
128 | async function getParentPath() { | 134 | async function getParentPath() { |
129 | const { appendClass } = props; | 135 | const { appendClass } = props; |
130 | if (!appendClass) return ''; | 136 | if (!appendClass) return ''; |
131 | const parentPath = await getCurrentParentPath(unref(currentRoute).path); | 137 | const parentPath = await getCurrentParentPath(unref(currentRoute).path); |
138 | + | ||
132 | currentParentPath.value = parentPath; | 139 | currentParentPath.value = parentPath; |
133 | } | 140 | } |
134 | 141 | ||
135 | - async function handleMenuClick(menu: MenuType) { | 142 | + async function handleMenuClick({ key, keyPath }: { key: string; keyPath: string[] }) { |
136 | const { beforeClickFn } = props; | 143 | const { beforeClickFn } = props; |
137 | if (beforeClickFn && isFunction(beforeClickFn)) { | 144 | if (beforeClickFn && isFunction(beforeClickFn)) { |
138 | - const flag = await beforeClickFn(menu); | 145 | + const flag = await beforeClickFn(key); |
139 | if (!flag) return; | 146 | if (!flag) return; |
140 | } | 147 | } |
141 | - emit('menuClick', menu); | ||
142 | - const { path } = menu; | ||
143 | - menuState.selectedKeys = [path]; | 148 | + emit('menuClick', key); |
149 | + | ||
150 | + isClickGo.value = true; | ||
151 | + menuState.openKeys = keyPath; | ||
152 | + menuState.selectedKeys = [key]; | ||
144 | } | 153 | } |
145 | 154 | ||
146 | function handleMenuChange() { | 155 | function handleMenuChange() { |
147 | - const { flatItems } = props; | ||
148 | - if (!unref(flatItems) || flatItems.length === 0) return; | ||
149 | - const findMenu = flatItems.find((menu) => menu.path === unref(currentRoute).path); | ||
150 | - if (findMenu) { | ||
151 | - if (menuState.mode !== MenuModeEnum.HORIZONTAL) { | ||
152 | - setOpenKeys(findMenu); | ||
153 | - } | ||
154 | - menuState.selectedKeys = [findMenu.path]; | ||
155 | - } else { | ||
156 | - resetKeys(); | 156 | + if (unref(isClickGo)) { |
157 | + isClickGo.value = false; | ||
158 | + return; | ||
157 | } | 159 | } |
160 | + const path = unref(currentRoute).path; | ||
161 | + if (menuState.mode !== MenuModeEnum.HORIZONTAL) { | ||
162 | + setOpenKeys(path); | ||
163 | + } | ||
164 | + menuState.selectedKeys = [path]; | ||
158 | } | 165 | } |
159 | 166 | ||
160 | - // render menu item | ||
161 | - function renderMenuItem(menuList?: MenuType[], index = 1) { | ||
162 | - if (!menuList) return; | 167 | + // function renderExpandIcon({ key }: { key: string }) { |
168 | + // const isOpen = getOpenKeys.value.includes(key); | ||
169 | + // const collapsed = unref(getCollapsed); | ||
170 | + // return ( | ||
171 | + // <BasicArrow | ||
172 | + // expand={isOpen} | ||
173 | + // bottom | ||
174 | + // inset | ||
175 | + // class={[ | ||
176 | + // `${prefixCls}__expand-icon`, | ||
177 | + // { | ||
178 | + // [`${prefixCls}__expand-icon--collapsed`]: collapsed, | ||
179 | + // }, | ||
180 | + // ]} | ||
181 | + // /> | ||
182 | + // ); | ||
183 | + // } | ||
184 | + | ||
185 | + function renderItem(menu: MenuType, level = 1) { | ||
186 | + return !menuHasChildren(menu) ? renderMenuItem(menu, level) : renderSubMenu(menu, level); | ||
187 | + } | ||
188 | + | ||
189 | + function renderMenuItem(menu: MenuType, level: number) { | ||
163 | const { appendClass } = props; | 190 | const { appendClass } = props; |
164 | - const levelCls = `basic-menu-item__level${index} ${menuState.theme} `; | ||
165 | - return menuList.map((menu) => { | ||
166 | - if (!menu) { | ||
167 | - return null; | ||
168 | - } | ||
169 | - | ||
170 | - const isAppendActiveCls = | ||
171 | - appendClass && index === 1 && menu.path === unref(currentParentPath); | ||
172 | - // ๆฒกๆๅญ่็น | ||
173 | - if (!menuHasChildren(menu)) { | ||
174 | - return ( | ||
175 | - <Menu.Item | ||
176 | - key={menu.path} | ||
177 | - class={`${levelCls}${isAppendActiveCls ? ' top-active-menu ' : ''}`} | ||
178 | - onClick={handleMenuClick.bind(null, menu)} | ||
179 | - > | ||
180 | - {() => [ | ||
181 | - <MenuContent | ||
182 | - item={menu} | ||
183 | - level={index} | ||
184 | - isHorizontal={props.isHorizontal} | ||
185 | - showTitle={unref(showTitle)} | ||
186 | - />, | ||
187 | - ]} | ||
188 | - </Menu.Item> | ||
189 | - ); | ||
190 | - } | ||
191 | - return ( | ||
192 | - <Menu.SubMenu key={menu.path} class={levelCls}> | ||
193 | - {{ | ||
194 | - title: () => [ | ||
195 | - <MenuContent | ||
196 | - showTitle={unref(showTitle)} | ||
197 | - item={menu} | ||
198 | - level={index} | ||
199 | - isHorizontal={props.isHorizontal} | ||
200 | - />, | ||
201 | - ], | ||
202 | - default: () => renderMenuItem(menu.children, index + 1), | ||
203 | - }} | ||
204 | - </Menu.SubMenu> | ||
205 | - ); | ||
206 | - }); | 191 | + const isAppendActiveCls = |
192 | + appendClass && level === 1 && menu.path === unref(currentParentPath); | ||
193 | + const levelCls = [ | ||
194 | + `${prefixCls}-item__level${level}`, | ||
195 | + ` ${menuState.theme} `, | ||
196 | + { | ||
197 | + 'top-active-menu': isAppendActiveCls, | ||
198 | + }, | ||
199 | + ]; | ||
200 | + return ( | ||
201 | + <Menu.Item key={menu.path} class={levelCls}> | ||
202 | + {() => [ | ||
203 | + <MenuContent | ||
204 | + item={menu} | ||
205 | + showTitle={unref(showTitle)} | ||
206 | + isHorizontal={props.isHorizontal} | ||
207 | + />, | ||
208 | + ]} | ||
209 | + </Menu.Item> | ||
210 | + ); | ||
211 | + } | ||
212 | + | ||
213 | + function renderSubMenu(menu: MenuType, level: number) { | ||
214 | + const levelCls = `${prefixCls}-item__level${level} ${menuState.theme} `; | ||
215 | + return ( | ||
216 | + <Menu.SubMenu key={menu.path} class={levelCls}> | ||
217 | + {{ | ||
218 | + title: () => [ | ||
219 | + <MenuContent | ||
220 | + showTitle={unref(showTitle)} | ||
221 | + item={menu} | ||
222 | + isHorizontal={props.isHorizontal} | ||
223 | + />, | ||
224 | + ], | ||
225 | + // expandIcon: renderExpandIcon, | ||
226 | + default: () => (menu.children || []).map((item) => renderItem(item, level + 1)), | ||
227 | + }} | ||
228 | + </Menu.SubMenu> | ||
229 | + ); | ||
207 | } | 230 | } |
208 | 231 | ||
209 | function renderMenu() { | 232 | function renderMenu() { |
210 | - const isInline = props.mode === MenuModeEnum.INLINE; | ||
211 | const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState; | 233 | const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState; |
212 | 234 | ||
213 | - const inlineCollapsedObj = isInline | ||
214 | - ? { | ||
215 | - inlineCollapsed: unref(getCollapsed), | ||
216 | - } | ||
217 | - : {}; | ||
218 | return ( | 235 | return ( |
219 | <Menu | 236 | <Menu |
220 | selectedKeys={selectedKeys} | 237 | selectedKeys={selectedKeys} |
@@ -224,36 +241,25 @@ export default defineComponent({ | @@ -224,36 +241,25 @@ export default defineComponent({ | ||
224 | inlineIndent={props.inlineIndent} | 241 | inlineIndent={props.inlineIndent} |
225 | theme={unref(theme)} | 242 | theme={unref(theme)} |
226 | onOpenChange={handleOpenChange} | 243 | onOpenChange={handleOpenChange} |
227 | - class={[ | ||
228 | - 'basic-menu', | ||
229 | - props.collapsedShowTitle && 'collapsed-show-title', | ||
230 | - ...unref(transparentMenuClass), | ||
231 | - ]} | ||
232 | - {...inlineCollapsedObj} | 244 | + class={unref(getMenuClass)} |
245 | + onClick={handleMenuClick} | ||
246 | + {...unref(getInlineCollapseOptions)} | ||
233 | > | 247 | > |
234 | {{ | 248 | {{ |
235 | - default: () => renderMenuItem(props.items, 1), | 249 | + default: () => unref(items).map((item) => renderItem(item)), |
236 | }} | 250 | }} |
237 | </Menu> | 251 | </Menu> |
238 | ); | 252 | ); |
239 | } | 253 | } |
240 | 254 | ||
241 | - onMounted(async () => { | ||
242 | - getParentPath(); | ||
243 | - }); | ||
244 | - | ||
245 | return () => { | 255 | return () => { |
246 | - const { mode } = props; | ||
247 | - return mode === MenuModeEnum.HORIZONTAL ? ( | ||
248 | - renderMenu() | ||
249 | - ) : ( | ||
250 | - <section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}> | ||
251 | - {getSlot(slots, 'header')} | ||
252 | - | ||
253 | - <section style={unref(getMenuWrapStyle)} class="basic-menu__content"> | 256 | + return ( |
257 | + <> | ||
258 | + {!unref(getIsHorizontal) && getSlot(slots, 'header')} | ||
259 | + <div class={`${prefixCls}-wrapper`} style={unref(getWrapperStyle)}> | ||
254 | {renderMenu()} | 260 | {renderMenu()} |
255 | - </section> | ||
256 | - </section> | 261 | + </div> |
262 | + </> | ||
257 | ); | 263 | ); |
258 | }; | 264 | }; |
259 | }, | 265 | }, |
src/components/Menu/src/BasicMenu.vue deleted
100644 โ 0
src/components/Menu/src/MenuContent.tsx
1 | import type { Menu as MenuType } from '/@/router/types'; | 1 | import type { Menu as MenuType } from '/@/router/types'; |
2 | -import { computed, PropType, unref } from 'vue'; | 2 | +import type { PropType } from 'vue'; |
3 | +import { computed, unref } from 'vue'; | ||
3 | 4 | ||
4 | import { defineComponent } from 'vue'; | 5 | import { defineComponent } from 'vue'; |
5 | import Icon from '/@/components/Icon/index'; | 6 | import Icon from '/@/components/Icon/index'; |
6 | import { useI18n } from '/@/hooks/web/useI18n'; | 7 | import { useI18n } from '/@/hooks/web/useI18n'; |
8 | +import { useDesign } from '/@/hooks/web/useDesign'; | ||
9 | + | ||
10 | +const { t } = useI18n(); | ||
7 | 11 | ||
8 | export default defineComponent({ | 12 | export default defineComponent({ |
9 | name: 'MenuContent', | 13 | name: 'MenuContent', |
@@ -12,12 +16,10 @@ export default defineComponent({ | @@ -12,12 +16,10 @@ export default defineComponent({ | ||
12 | type: Object as PropType<MenuType>, | 16 | type: Object as PropType<MenuType>, |
13 | default: null, | 17 | default: null, |
14 | }, | 18 | }, |
15 | - | ||
16 | showTitle: { | 19 | showTitle: { |
17 | type: Boolean as PropType<boolean>, | 20 | type: Boolean as PropType<boolean>, |
18 | default: true, | 21 | default: true, |
19 | }, | 22 | }, |
20 | - | ||
21 | level: { | 23 | level: { |
22 | type: Number as PropType<number>, | 24 | type: Number as PropType<number>, |
23 | default: 0, | 25 | default: 0, |
@@ -28,13 +30,32 @@ export default defineComponent({ | @@ -28,13 +30,32 @@ export default defineComponent({ | ||
28 | }, | 30 | }, |
29 | }, | 31 | }, |
30 | setup(props) { | 32 | setup(props) { |
31 | - const { t } = useI18n(); | 33 | + const { prefixCls } = useDesign('basic-menu'); |
32 | 34 | ||
33 | const getI18nName = computed(() => t(props.item?.name)); | 35 | const getI18nName = computed(() => t(props.item?.name)); |
36 | + | ||
37 | + const getTagClass = computed(() => { | ||
38 | + const { item } = props; | ||
39 | + const { tag = {} } = item || {}; | ||
40 | + const { dot, type = 'error' } = tag; | ||
41 | + return [ | ||
42 | + `${prefixCls}__tag`, | ||
43 | + type, | ||
44 | + { | ||
45 | + dot, | ||
46 | + }, | ||
47 | + ]; | ||
48 | + }); | ||
49 | + | ||
50 | + const getNameClass = computed(() => { | ||
51 | + const { showTitle } = props; | ||
52 | + return { [`${prefixCls}--show-title`]: showTitle, [`${prefixCls}__name`]: !showTitle }; | ||
53 | + }); | ||
54 | + | ||
34 | /** | 55 | /** |
35 | * @description: ๆธฒๆๅพๆ | 56 | * @description: ๆธฒๆๅพๆ |
36 | */ | 57 | */ |
37 | - function renderIcon(icon: string) { | 58 | + function renderIcon(icon?: string) { |
38 | return icon ? <Icon icon={icon} size={18} class="menu-item-icon" /> : null; | 59 | return icon ? <Icon icon={icon} size={18} class="menu-item-icon" /> : null; |
39 | } | 60 | } |
40 | 61 | ||
@@ -45,36 +66,30 @@ export default defineComponent({ | @@ -45,36 +66,30 @@ export default defineComponent({ | ||
45 | const { tag } = item; | 66 | const { tag } = item; |
46 | if (!tag) return null; | 67 | if (!tag) return null; |
47 | 68 | ||
48 | - const { dot, content, type = 'error' } = tag; | 69 | + const { dot, content } = tag; |
49 | if (!dot && !content) return null; | 70 | if (!dot && !content) return null; |
50 | - const cls = ['basic-menu__tag']; | ||
51 | - | ||
52 | - dot && cls.push('dot'); | ||
53 | - type && cls.push(type); | ||
54 | 71 | ||
55 | - return <span class={cls}>{dot ? '' : content}</span>; | 72 | + return <span class={unref(getTagClass)}>{dot ? '' : content}</span>; |
56 | } | 73 | } |
57 | 74 | ||
58 | return () => { | 75 | return () => { |
59 | - if (!props.item) { | 76 | + const { item } = props; |
77 | + if (!item) { | ||
60 | return null; | 78 | return null; |
61 | } | 79 | } |
62 | - const { showTitle } = props; | ||
63 | - const { icon } = props.item; | 80 | + const { icon } = item; |
64 | const name = unref(getI18nName); | 81 | const name = unref(getI18nName); |
65 | 82 | ||
66 | - const cls = showTitle ? ['show-title'] : ['basic-menu__name']; | ||
67 | - | ||
68 | return ( | 83 | return ( |
69 | - <> | ||
70 | - {renderIcon(icon!)} | 84 | + <span class={`${prefixCls}__content-wrapper`}> |
85 | + {renderIcon(icon)} | ||
71 | { | 86 | { |
72 | - <span class={[cls]}> | 87 | + <span class={unref(getNameClass)}> |
73 | {name} | 88 | {name} |
74 | {renderTag()} | 89 | {renderTag()} |
75 | </span> | 90 | </span> |
76 | } | 91 | } |
77 | - </> | 92 | + </span> |
78 | ); | 93 | ); |
79 | }; | 94 | }; |
80 | }, | 95 | }, |
src/components/Menu/src/index.less
1 | @import (reference) '../../../design/index.less'; | 1 | @import (reference) '../../../design/index.less'; |
2 | 2 | ||
3 | +@basic-menu-prefix-cls: ~'@{namespace}-basic-menu'; | ||
4 | + | ||
3 | .active-style() { | 5 | .active-style() { |
4 | color: @white; | 6 | color: @white; |
5 | background: linear-gradient( | 7 | background: linear-gradient( |
@@ -16,21 +18,48 @@ | @@ -16,21 +18,48 @@ | ||
16 | } | 18 | } |
17 | } | 19 | } |
18 | 20 | ||
19 | -.basic-menu { | 21 | +.@{basic-menu-prefix-cls} { |
20 | width: 100%; | 22 | width: 100%; |
21 | 23 | ||
22 | - &-wrap { | ||
23 | - height: 100%; | ||
24 | - } | 24 | + // &__expand-icon { |
25 | + // position: absolute; | ||
26 | + // top: calc(50% - 6px); | ||
27 | + // right: 16px; | ||
28 | + // width: 10px; | ||
29 | + // transform-origin: none; | ||
30 | + | ||
31 | + // span[role='img'] { | ||
32 | + // margin-right: 0; | ||
33 | + // font-size: 11px; | ||
34 | + // } | ||
35 | + | ||
36 | + // &--collapsed { | ||
37 | + // opacity: 0; | ||
38 | + // } | ||
39 | + // } | ||
25 | 40 | ||
26 | // collapsed show title start | 41 | // collapsed show title start |
27 | - .show-title { | 42 | + &--show-title { |
28 | max-width: unset !important; | 43 | max-width: unset !important; |
29 | opacity: 1 !important; | 44 | opacity: 1 !important; |
30 | } | 45 | } |
31 | 46 | ||
32 | - &.collapsed-show-title.ant-menu-inline-collapsed { | ||
33 | - .basic-menu-item__level1 { | 47 | + &--hide-title { |
48 | + &.ant-menu-inline-collapsed > .ant-menu-item, | ||
49 | + &.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item, | ||
50 | + &.ant-menu-inline-collapsed | ||
51 | + > .ant-menu-item-group | ||
52 | + > .ant-menu-item-group-list | ||
53 | + > .ant-menu-submenu | ||
54 | + > .ant-menu-submenu-title, | ||
55 | + &.ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title { | ||
56 | + padding-right: 20px !important; | ||
57 | + padding-left: 20px !important; | ||
58 | + } | ||
59 | + } | ||
60 | + | ||
61 | + &--collapsed-show-title.ant-menu-inline-collapsed { | ||
62 | + .@{basic-menu-prefix-cls}-item__level1 { | ||
34 | padding: 2px 0; | 63 | padding: 2px 0; |
35 | } | 64 | } |
36 | 65 | ||
@@ -47,14 +76,23 @@ | @@ -47,14 +76,23 @@ | ||
47 | & > li > .ant-menu-submenu-title { | 76 | & > li > .ant-menu-submenu-title { |
48 | line-height: 24px; | 77 | line-height: 24px; |
49 | } | 78 | } |
79 | + .@{basic-menu-prefix-cls}__content-wrapper { | ||
80 | + display: flex; | ||
81 | + justify-content: center; | ||
82 | + align-items: center; | ||
83 | + flex-direction: column; | ||
84 | + .@{basic-menu-prefix-cls}--show-title { | ||
85 | + line-height: 30px; | ||
86 | + } | ||
87 | + } | ||
50 | } | 88 | } |
51 | 89 | ||
52 | - .ant-menu-item { | ||
53 | - transition: unset; | ||
54 | - } | 90 | + // .ant-menu-item { |
91 | + // transition: unset; | ||
92 | + // } | ||
55 | 93 | ||
56 | // scrollbar -s tart | 94 | // scrollbar -s tart |
57 | - &__content { | 95 | + &-wrapper { |
58 | /* ๆปๅจๆงฝ */ | 96 | /* ๆปๅจๆงฝ */ |
59 | &::-webkit-scrollbar { | 97 | &::-webkit-scrollbar { |
60 | width: 5px; | 98 | width: 5px; |
@@ -75,8 +113,20 @@ | @@ -75,8 +113,20 @@ | ||
75 | background: @border-color-dark; | 113 | background: @border-color-dark; |
76 | } | 114 | } |
77 | } | 115 | } |
116 | + | ||
78 | // scrollbar end | 117 | // scrollbar end |
79 | 118 | ||
119 | + &-item__level1.light { | ||
120 | + &.top-active-menu { | ||
121 | + top: 0 !important; | ||
122 | + } | ||
123 | + | ||
124 | + &.top-active-menu:not(.ant-menu-item-selected) { | ||
125 | + color: @primary-color; | ||
126 | + border-bottom: 3px solid @primary-color; | ||
127 | + } | ||
128 | + } | ||
129 | + | ||
80 | &__sidebar-hor { | 130 | &__sidebar-hor { |
81 | // overflow: hidden; | 131 | // overflow: hidden; |
82 | 132 | ||
@@ -85,20 +135,13 @@ | @@ -85,20 +135,13 @@ | ||
85 | border: 0; | 135 | border: 0; |
86 | align-items: center; | 136 | align-items: center; |
87 | 137 | ||
88 | - .basic-menu-item__level1 { | 138 | + .@{basic-menu-prefix-cls}-item__level1 { |
89 | margin-right: 2px; | 139 | margin-right: 2px; |
90 | } | 140 | } |
91 | 141 | ||
92 | &.ant-menu-light { | 142 | &.ant-menu-light { |
93 | - .basic-menu-item__level1 { | ||
94 | - &.top-active-menu { | ||
95 | - color: @primary-color; | ||
96 | - border-bottom: 3px solid @primary-color; | ||
97 | - } | ||
98 | - } | ||
99 | - | ||
100 | .ant-menu-item { | 143 | .ant-menu-item { |
101 | - &.basic-menu-item__level1 { | 144 | + &.@{basic-menu-prefix-cls}-item__level1 { |
102 | height: @header-height; | 145 | height: @header-height; |
103 | line-height: @header-height; | 146 | line-height: @header-height; |
104 | } | 147 | } |
@@ -155,7 +198,7 @@ | @@ -155,7 +198,7 @@ | ||
155 | background: @top-menu-active-bg-color; | 198 | background: @top-menu-active-bg-color; |
156 | } | 199 | } |
157 | 200 | ||
158 | - .basic-menu-item__level1 { | 201 | + .@{basic-menu-prefix-cls}-item__level1 { |
159 | background: transparent; | 202 | background: transparent; |
160 | 203 | ||
161 | &.top-active-menu { | 204 | &.top-active-menu { |
@@ -172,7 +215,7 @@ | @@ -172,7 +215,7 @@ | ||
172 | 215 | ||
173 | .ant-menu-item, | 216 | .ant-menu-item, |
174 | .ant-menu-submenu { | 217 | .ant-menu-submenu { |
175 | - &.basic-menu-item__level1, | 218 | + &.@{basic-menu-prefix-cls}-item__level1, |
176 | .ant-menu-submenu-title { | 219 | .ant-menu-submenu-title { |
177 | height: @header-height; | 220 | height: @header-height; |
178 | line-height: @header-height; | 221 | line-height: @header-height; |
@@ -182,17 +225,17 @@ | @@ -182,17 +225,17 @@ | ||
182 | } | 225 | } |
183 | } | 226 | } |
184 | 227 | ||
185 | - &:not(.basic-menu__sidebar-hor).ant-menu-inline-collapsed { | ||
186 | - .basic-menu-item__level1 { | 228 | + &:not(.@{basic-menu-prefix-cls}__sidebar-hor).ant-menu-inline-collapsed { |
229 | + .@{basic-menu-prefix-cls}-item__level1 { | ||
187 | > div { | 230 | > div { |
188 | align-items: center; | 231 | align-items: center; |
189 | } | 232 | } |
190 | } | 233 | } |
191 | } | 234 | } |
192 | 235 | ||
193 | - &.ant-menu-dark:not(.basic-menu__sidebar-hor):not(.basic-menu__second) { | 236 | + &.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor):not(.@{basic-menu-prefix-cls}__second) { |
194 | // Reset menu item row height | 237 | // Reset menu item row height |
195 | - .ant-menu-item:not(.basic-menu-item__level1), | 238 | + .ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1), |
196 | .ant-menu-sub.ant-menu-inline > .ant-menu-item, | 239 | .ant-menu-sub.ant-menu-inline > .ant-menu-item, |
197 | .ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title { | 240 | .ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title { |
198 | height: @app-menu-item-height; | 241 | height: @app-menu-item-height; |
@@ -200,28 +243,28 @@ | @@ -200,28 +243,28 @@ | ||
200 | line-height: @app-menu-item-height; | 243 | line-height: @app-menu-item-height; |
201 | } | 244 | } |
202 | 245 | ||
203 | - .ant-menu-item.basic-menu-item__level1 { | 246 | + .ant-menu-item.@{basic-menu-prefix-cls}-item__level1 { |
204 | height: @app-menu-item-height; | 247 | height: @app-menu-item-height; |
205 | line-height: @app-menu-item-height; | 248 | line-height: @app-menu-item-height; |
206 | } | 249 | } |
207 | } | 250 | } |
208 | 251 | ||
209 | // ๅฑ็บงๆ ทๅผ | 252 | // ๅฑ็บงๆ ทๅผ |
210 | - &.ant-menu-dark:not(.basic-menu__sidebar-hor) { | ||
211 | - overflow-x: hidden; | 253 | + &.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor) { |
254 | + overflow: hidden; | ||
212 | background: @sider-dark-bg-color; | 255 | background: @sider-dark-bg-color; |
213 | .active-menu-style(); | 256 | .active-menu-style(); |
214 | 257 | ||
215 | - .menu-item-icon.app-iconify { | ||
216 | - display: inline-block !important; | ||
217 | - } | 258 | + // .menu-item-icon.app-iconify { |
259 | + // display: inline-block !important; | ||
260 | + // } | ||
218 | 261 | ||
219 | - .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1, | ||
220 | - .ant-menu-submenu-selected.basic-menu-menu-item__level1 { | 262 | + .ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1, |
263 | + .ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 { | ||
221 | color: @white; | 264 | color: @white; |
222 | } | 265 | } |
223 | 266 | ||
224 | - .basic-menu-item__level1 { | 267 | + .@{basic-menu-prefix-cls}-item__level1 { |
225 | background-color: @sider-dark-bg-color; | 268 | background-color: @sider-dark-bg-color; |
226 | 269 | ||
227 | > .ant-menu-sub > li { | 270 | > .ant-menu-sub > li { |
@@ -229,12 +272,12 @@ | @@ -229,12 +272,12 @@ | ||
229 | } | 272 | } |
230 | } | 273 | } |
231 | 274 | ||
232 | - .basic-menu-item__level2:not(.ant-menu-item-selected), | 275 | + .@{basic-menu-prefix-cls}-item__level2:not(.ant-menu-item-selected), |
233 | .ant-menu-sub { | 276 | .ant-menu-sub { |
234 | background-color: @sider-dark-lighten-1-bg-color; | 277 | background-color: @sider-dark-lighten-1-bg-color; |
235 | } | 278 | } |
236 | 279 | ||
237 | - .basic-menu-item__level3:not(.ant-menu-item-selected) { | 280 | + .@{basic-menu-prefix-cls}-item__level3:not(.ant-menu-item-selected) { |
238 | background-color: @sider-dark-lighten-2-bg-color; | 281 | background-color: @sider-dark-lighten-2-bg-color; |
239 | 282 | ||
240 | .ant-menu-item { | 283 | .ant-menu-item { |
@@ -257,35 +300,26 @@ | @@ -257,35 +300,26 @@ | ||
257 | } | 300 | } |
258 | } | 301 | } |
259 | 302 | ||
260 | - &.ant-menu-light:not(.basic-menu__sidebar-hor) { | ||
261 | - overflow-x: hidden; | 303 | + &.ant-menu-light:not(.@{basic-menu-prefix-cls}__sidebar-hor) { |
304 | + overflow: hidden; | ||
262 | border-right: none; | 305 | border-right: none; |
263 | 306 | ||
264 | - .menu-item-icon.app-iconify { | ||
265 | - display: inline-block !important; | ||
266 | - } | ||
267 | - | ||
268 | - // .ant-menu-item-selected { | ||
269 | - // background: fade(@primary-color, 18%); | 307 | + // .menu-item-icon.app-iconify { |
308 | + // display: inline-block !important; | ||
270 | // } | 309 | // } |
271 | 310 | ||
272 | - .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1, | ||
273 | - .ant-menu-submenu-selected.basic-menu-menu-item__level1 { | 311 | + .ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1, |
312 | + .ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 { | ||
274 | color: @primary-color; | 313 | color: @primary-color; |
275 | } | 314 | } |
276 | } | 315 | } |
277 | 316 | ||
278 | - // ๅ ณ้ฎๅญ็้ข่ฒ | ||
279 | - &__keyword { | ||
280 | - color: lighten(@primary-color, 20%); | ||
281 | - } | ||
282 | - | ||
283 | // ๆฟๆดป็ๅญ่ๅๆ ทๅผ | 317 | // ๆฟๆดป็ๅญ่ๅๆ ทๅผ |
284 | .ant-menu-item.ant-menu-item-selected { | 318 | .ant-menu-item.ant-menu-item-selected { |
285 | position: relative; | 319 | position: relative; |
286 | } | 320 | } |
287 | 321 | ||
288 | - &.basic-menu__second.ant-menu-inline-collapsed:not(.basic-menu__sidebar-hor) { | 322 | + &.@{basic-menu-prefix-cls}__second.ant-menu-inline-collapsed:not(.@{basic-menu-prefix-cls}__sidebar-hor) { |
289 | // Reset menu item row height | 323 | // Reset menu item row height |
290 | .ant-menu-item, | 324 | .ant-menu-item, |
291 | .ant-menu-sub.ant-menu-inline > .ant-menu-item, | 325 | .ant-menu-sub.ant-menu-inline > .ant-menu-item, |
@@ -298,26 +332,40 @@ | @@ -298,26 +332,40 @@ | ||
298 | align-items: center; | 332 | align-items: center; |
299 | } | 333 | } |
300 | } | 334 | } |
301 | -} | 335 | + .@{basic-menu-prefix-cls}__tag { |
336 | + position: absolute; | ||
337 | + top: calc(50% - 8px); | ||
338 | + right: 30px; | ||
339 | + display: inline-block; | ||
340 | + padding: 2px 4px; | ||
341 | + margin-right: 4px; | ||
342 | + font-size: 12px; | ||
343 | + line-height: 14px; | ||
344 | + color: #fff; | ||
345 | + border-radius: 2px; | ||
346 | + | ||
347 | + &.dot { | ||
348 | + top: calc(50% - 4px); | ||
349 | + width: 8px; | ||
350 | + height: 8px; | ||
351 | + padding: 0; | ||
352 | + border-radius: 50%; | ||
353 | + } | ||
302 | 354 | ||
303 | -// ่งฆๅๅจๆ ทๅผ | ||
304 | -.ant-layout-sider { | ||
305 | - &-dark { | ||
306 | - .ant-layout-sider-trigger { | ||
307 | - color: darken(@white, 25%); | ||
308 | - background: @trigger-dark-bg-color; | 355 | + &.primary { |
356 | + background: @primary-color; | ||
357 | + } | ||
309 | 358 | ||
310 | - &:hover { | ||
311 | - color: @white; | ||
312 | - background: @trigger-dark-hover-bg-color; | ||
313 | - } | 359 | + &.error { |
360 | + background: @error-color; | ||
361 | + } | ||
362 | + | ||
363 | + &.success { | ||
364 | + background: @success-color; | ||
314 | } | 365 | } |
315 | - } | ||
316 | 366 | ||
317 | - &-light { | ||
318 | - .ant-layout-sider-trigger { | ||
319 | - color: @text-color-base; | ||
320 | - border-top: 1px solid @border-color-light; | 367 | + &.warn { |
368 | + background: @warning-color; | ||
321 | } | 369 | } |
322 | } | 370 | } |
323 | } | 371 | } |
@@ -332,71 +380,16 @@ | @@ -332,71 +380,16 @@ | ||
332 | } | 380 | } |
333 | } | 381 | } |
334 | 382 | ||
335 | -.hide-title { | ||
336 | - .ant-menu-inline-collapsed > .ant-menu-item, | ||
337 | - .ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item, | ||
338 | - .ant-menu-inline-collapsed | ||
339 | - > .ant-menu-item-group | ||
340 | - > .ant-menu-item-group-list | ||
341 | - > .ant-menu-submenu | ||
342 | - > .ant-menu-submenu-title, | ||
343 | - .ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title { | ||
344 | - padding-right: 20px !important; | ||
345 | - padding-left: 20px !important; | ||
346 | - } | ||
347 | - | ||
348 | - .ant-menu-inline-collapsed { | ||
349 | - .basic-menu-item__level1 { | ||
350 | - display: flex; | ||
351 | - justify-content: center; | ||
352 | - } | ||
353 | - } | ||
354 | -} | ||
355 | // collapsed show title end | 383 | // collapsed show title end |
356 | .ant-menu-item, | 384 | .ant-menu-item, |
357 | .ant-menu-submenu-title { | 385 | .ant-menu-submenu-title { |
358 | - > .basic-menu__name { | 386 | + > .@{basic-menu-prefix-cls}__name { |
359 | width: 100%; | 387 | width: 100%; |
360 | 388 | ||
361 | - .basic-menu__tag { | 389 | + .@{basic-menu-prefix-cls}__tag { |
362 | float: right; | 390 | float: right; |
363 | margin-top: @app-menu-item-height / 2; | 391 | margin-top: @app-menu-item-height / 2; |
364 | transform: translate(0%, -50%); | 392 | transform: translate(0%, -50%); |
365 | } | 393 | } |
366 | } | 394 | } |
367 | } | 395 | } |
368 | - | ||
369 | -.basic-menu__tag { | ||
370 | - display: inline-block; | ||
371 | - padding: 2px 4px; | ||
372 | - margin-right: 4px; | ||
373 | - font-size: 12px; | ||
374 | - line-height: 14px; | ||
375 | - color: #fff; | ||
376 | - border-radius: 2px; | ||
377 | - | ||
378 | - &.dot { | ||
379 | - width: 8px; | ||
380 | - height: 8px; | ||
381 | - padding: 0; | ||
382 | - margin-top: 21px !important; | ||
383 | - margin-bottom: 2px; | ||
384 | - border-radius: 50%; | ||
385 | - } | ||
386 | - | ||
387 | - &.primary { | ||
388 | - background: @primary-color; | ||
389 | - } | ||
390 | - | ||
391 | - &.error { | ||
392 | - background: @error-color; | ||
393 | - } | ||
394 | - | ||
395 | - &.success { | ||
396 | - background: @success-color; | ||
397 | - } | ||
398 | - | ||
399 | - &.warn { | ||
400 | - background: @warning-color; | ||
401 | - } | ||
402 | -} |
src/components/Menu/src/props.ts
@@ -8,14 +8,11 @@ export const basicProps = { | @@ -8,14 +8,11 @@ export const basicProps = { | ||
8 | type: Array as PropType<Menu[]>, | 8 | type: Array as PropType<Menu[]>, |
9 | default: () => [], | 9 | default: () => [], |
10 | }, | 10 | }, |
11 | - flatItems: { | ||
12 | - type: Array as PropType<Menu[]>, | ||
13 | - default: () => [], | ||
14 | - }, | ||
15 | appendClass: { | 11 | appendClass: { |
16 | type: Boolean as PropType<boolean>, | 12 | type: Boolean as PropType<boolean>, |
17 | default: false, | 13 | default: false, |
18 | }, | 14 | }, |
15 | + | ||
19 | collapsedShowTitle: { | 16 | collapsedShowTitle: { |
20 | type: Boolean as PropType<boolean>, | 17 | type: Boolean as PropType<boolean>, |
21 | default: false, | 18 | default: false, |
@@ -31,6 +28,10 @@ export const basicProps = { | @@ -31,6 +28,10 @@ export const basicProps = { | ||
31 | type: String as PropType<MenuModeEnum>, | 28 | type: String as PropType<MenuModeEnum>, |
32 | default: MenuModeEnum.INLINE, | 29 | default: MenuModeEnum.INLINE, |
33 | }, | 30 | }, |
31 | + showLogo: { | ||
32 | + type: Boolean as PropType<boolean>, | ||
33 | + default: false, | ||
34 | + }, | ||
34 | type: { | 35 | type: { |
35 | type: String as PropType<MenuTypeEnum>, | 36 | type: String as PropType<MenuTypeEnum>, |
36 | default: MenuTypeEnum.MIX, | 37 | default: MenuTypeEnum.MIX, |
@@ -39,10 +40,6 @@ export const basicProps = { | @@ -39,10 +40,6 @@ export const basicProps = { | ||
39 | type: String as PropType<string>, | 40 | type: String as PropType<string>, |
40 | default: ThemeEnum.DARK, | 41 | default: ThemeEnum.DARK, |
41 | }, | 42 | }, |
42 | - showLogo: { | ||
43 | - type: Boolean as PropType<boolean>, | ||
44 | - default: false, | ||
45 | - }, | ||
46 | inlineCollapsed: { | 43 | inlineCollapsed: { |
47 | type: Boolean as PropType<boolean>, | 44 | type: Boolean as PropType<boolean>, |
48 | default: false, | 45 | default: false, |
@@ -57,7 +54,6 @@ export const basicProps = { | @@ -57,7 +54,6 @@ export const basicProps = { | ||
57 | default: true, | 54 | default: true, |
58 | }, | 55 | }, |
59 | beforeClickFn: { | 56 | beforeClickFn: { |
60 | - type: Function as PropType<Fn>, | ||
61 | - default: null, | 57 | + type: Function as PropType<(key: string) => Promise<boolean>>, |
62 | }, | 58 | }, |
63 | }; | 59 | }; |
src/components/Menu/src/useOpenKeys.ts
1 | import { MenuModeEnum } from '/@/enums/menuEnum'; | 1 | import { MenuModeEnum } from '/@/enums/menuEnum'; |
2 | import type { Menu as MenuType } from '/@/router/types'; | 2 | import type { Menu as MenuType } from '/@/router/types'; |
3 | import type { MenuState } from './types'; | 3 | import type { MenuState } from './types'; |
4 | -import type { Ref } from 'vue'; | 4 | + |
5 | +import { computed, Ref, toRaw } from 'vue'; | ||
5 | 6 | ||
6 | import { unref } from 'vue'; | 7 | import { unref } from 'vue'; |
7 | -import { getAllParentPath } from '/@/router/helper/menuHelper'; | ||
8 | import { es6Unique } from '/@/utils'; | 8 | import { es6Unique } from '/@/utils'; |
9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
10 | +import { getAllParentPath } from '/@/router/helper/menuHelper'; | ||
10 | 11 | ||
11 | export function useOpenKeys( | 12 | export function useOpenKeys( |
12 | menuState: MenuState, | 13 | menuState: MenuState, |
13 | menus: Ref<MenuType[]>, | 14 | menus: Ref<MenuType[]>, |
14 | - flatMenusRef: Ref<MenuType[]>, | ||
15 | mode: Ref<MenuModeEnum>, | 15 | mode: Ref<MenuModeEnum>, |
16 | accordion: Ref<boolean> | 16 | accordion: Ref<boolean> |
17 | ) { | 17 | ) { |
18 | const { getCollapsed } = useMenuSetting(); | 18 | const { getCollapsed } = useMenuSetting(); |
19 | 19 | ||
20 | - function setOpenKeys(menu: MenuType) { | ||
21 | - const flatMenus = unref(flatMenusRef); | 20 | + function setOpenKeys(path: string) { |
21 | + const menuList = toRaw(menus.value); | ||
22 | if (!unref(accordion)) { | 22 | if (!unref(accordion)) { |
23 | - menuState.openKeys = es6Unique([ | ||
24 | - ...menuState.openKeys, | ||
25 | - ...getAllParentPath(flatMenus, menu.path), | ||
26 | - ]); | 23 | + menuState.openKeys = es6Unique([...menuState.openKeys, ...getAllParentPath(menuList, path)]); |
27 | } else { | 24 | } else { |
28 | - menuState.openKeys = getAllParentPath(flatMenus, menu.path); | 25 | + menuState.openKeys = getAllParentPath(menuList, path); |
29 | } | 26 | } |
30 | } | 27 | } |
31 | 28 | ||
29 | + const getOpenKeys = computed(() => { | ||
30 | + return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys; | ||
31 | + }); | ||
32 | + | ||
32 | /** | 33 | /** |
33 | * @description: ้็ฝฎๅผ | 34 | * @description: ้็ฝฎๅผ |
34 | */ | 35 | */ |
@@ -59,5 +60,5 @@ export function useOpenKeys( | @@ -59,5 +60,5 @@ export function useOpenKeys( | ||
59 | } | 60 | } |
60 | } | 61 | } |
61 | } | 62 | } |
62 | - return { setOpenKeys, resetKeys, handleOpenChange }; | 63 | + return { setOpenKeys, resetKeys, getOpenKeys, handleOpenChange }; |
63 | } | 64 | } |
src/hooks/setting/useHeaderSetting.ts
@@ -11,76 +11,76 @@ import { useFullContent } from '/@/hooks/web/useFullContent'; | @@ -11,76 +11,76 @@ import { useFullContent } from '/@/hooks/web/useFullContent'; | ||
11 | 11 | ||
12 | import { MenuModeEnum } from '/@/enums/menuEnum'; | 12 | import { MenuModeEnum } from '/@/enums/menuEnum'; |
13 | 13 | ||
14 | -export function useHeaderSetting() { | ||
15 | - const { getFullContent } = useFullContent(); | ||
16 | - const { getShowMultipleTab } = useMultipleTabSetting(); | ||
17 | - const { | ||
18 | - getMenuMode, | ||
19 | - getSplit, | ||
20 | - getShowHeaderTrigger, | ||
21 | - getIsSidebarType, | ||
22 | - getIsTopMenu, | ||
23 | - } = useMenuSetting(); | ||
24 | - const { getShowBreadCrumb, getShowLogo } = useRootSetting(); | 14 | +const { getFullContent } = useFullContent(); |
15 | +const { getShowMultipleTab } = useMultipleTabSetting(); | ||
16 | +const { | ||
17 | + getMenuMode, | ||
18 | + getSplit, | ||
19 | + getShowHeaderTrigger, | ||
20 | + getIsSidebarType, | ||
21 | + getIsTopMenu, | ||
22 | +} = useMenuSetting(); | ||
23 | +const { getShowBreadCrumb, getShowLogo } = useRootSetting(); | ||
25 | 24 | ||
26 | - const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader)); | 25 | +const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader)); |
27 | 26 | ||
28 | - const getShowFullHeaderRef = computed(() => { | ||
29 | - return ( | ||
30 | - !unref(getFullContent) && | ||
31 | - unref(getShowMixHeaderRef) && | ||
32 | - unref(getShowHeader) && | ||
33 | - !unref(getIsTopMenu) | ||
34 | - ); | ||
35 | - }); | 27 | +const getShowFullHeaderRef = computed(() => { |
28 | + return ( | ||
29 | + !unref(getFullContent) && | ||
30 | + unref(getShowMixHeaderRef) && | ||
31 | + unref(getShowHeader) && | ||
32 | + !unref(getIsTopMenu) | ||
33 | + ); | ||
34 | +}); | ||
36 | 35 | ||
37 | - const getShowInsetHeaderRef = computed(() => { | ||
38 | - const need = !unref(getFullContent) && unref(getShowHeader); | ||
39 | - return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu)); | ||
40 | - }); | 36 | +const getShowInsetHeaderRef = computed(() => { |
37 | + const need = !unref(getFullContent) && unref(getShowHeader); | ||
38 | + return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu)); | ||
39 | +}); | ||
41 | 40 | ||
42 | - // Get header configuration | ||
43 | - const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting); | 41 | +// Get header configuration |
42 | +const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting); | ||
44 | 43 | ||
45 | - const getShowDoc = computed(() => unref(getHeaderSetting).showDoc); | 44 | +const getShowDoc = computed(() => unref(getHeaderSetting).showDoc); |
46 | 45 | ||
47 | - const getHeaderTheme = computed(() => unref(getHeaderSetting).theme); | 46 | +const getHeaderTheme = computed(() => unref(getHeaderSetting).theme); |
48 | 47 | ||
49 | - const getShowHeader = computed(() => unref(getHeaderSetting).show); | 48 | +const getShowHeader = computed(() => unref(getHeaderSetting).show); |
50 | 49 | ||
51 | - const getFixed = computed(() => unref(getHeaderSetting).fixed); | 50 | +const getFixed = computed(() => unref(getHeaderSetting).fixed); |
52 | 51 | ||
53 | - const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor); | 52 | +const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor); |
54 | 53 | ||
55 | - const getShowRedo = computed(() => unref(getHeaderSetting).showRedo && unref(getShowMultipleTab)); | 54 | +const getShowRedo = computed(() => unref(getHeaderSetting).showRedo && unref(getShowMultipleTab)); |
56 | 55 | ||
57 | - const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage); | 56 | +const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage); |
58 | 57 | ||
59 | - const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen); | 58 | +const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen); |
60 | 59 | ||
61 | - const getShowNotice = computed(() => unref(getHeaderSetting).showNotice); | 60 | +const getShowNotice = computed(() => unref(getHeaderSetting).showNotice); |
62 | 61 | ||
63 | - const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef)); | 62 | +const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef)); |
64 | 63 | ||
65 | - const getShowBread = computed(() => { | ||
66 | - return ( | ||
67 | - unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit) | ||
68 | - ); | ||
69 | - }); | 64 | +const getShowBread = computed(() => { |
65 | + return ( | ||
66 | + unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit) | ||
67 | + ); | ||
68 | +}); | ||
70 | 69 | ||
71 | - const getShowHeaderLogo = computed(() => { | ||
72 | - return unref(getShowLogo) && !unref(getIsSidebarType); | ||
73 | - }); | 70 | +const getShowHeaderLogo = computed(() => { |
71 | + return unref(getShowLogo) && !unref(getIsSidebarType); | ||
72 | +}); | ||
74 | 73 | ||
75 | - const getShowContent = computed(() => { | ||
76 | - return unref(getShowBread) || unref(getShowHeaderTrigger); | ||
77 | - }); | 74 | +const getShowContent = computed(() => { |
75 | + return unref(getShowBread) || unref(getShowHeaderTrigger); | ||
76 | +}); | ||
78 | 77 | ||
79 | - // Set header configuration | ||
80 | - function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void { | ||
81 | - appStore.commitProjectConfigState({ headerSetting }); | ||
82 | - } | 78 | +// Set header configuration |
79 | +function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void { | ||
80 | + appStore.commitProjectConfigState({ headerSetting }); | ||
81 | +} | ||
83 | 82 | ||
83 | +export function useHeaderSetting() { | ||
84 | return { | 84 | return { |
85 | setHeaderSetting, | 85 | setHeaderSetting, |
86 | 86 |
src/hooks/setting/useLocaleSetting.ts
@@ -6,26 +6,26 @@ import { appStore } from '/@/store/modules/app'; | @@ -6,26 +6,26 @@ import { appStore } from '/@/store/modules/app'; | ||
6 | import getProjectSetting from '/@/settings/projectSetting'; | 6 | import getProjectSetting from '/@/settings/projectSetting'; |
7 | import { localeList } from '/@/locales'; | 7 | import { localeList } from '/@/locales'; |
8 | 8 | ||
9 | -export function useLocaleSetting() { | ||
10 | - // Get locale configuration | ||
11 | - const getLocale = computed(() => appStore.getProjectConfig.locale || getProjectSetting.locale); | 9 | +// Get locale configuration |
10 | +const getLocale = computed(() => appStore.getProjectConfig.locale || getProjectSetting.locale); | ||
12 | 11 | ||
13 | - // get current language | ||
14 | - const getLang = computed(() => unref(getLocale).lang); | 12 | +// get current language |
13 | +const getLang = computed(() => unref(getLocale).lang); | ||
15 | 14 | ||
16 | - // get Available Locales | ||
17 | - const getAvailableLocales = computed((): string[] => unref(getLocale).availableLocales); | 15 | +// get Available Locales |
16 | +const getAvailableLocales = computed((): string[] => unref(getLocale).availableLocales); | ||
18 | 17 | ||
19 | - // get Fallback Locales | ||
20 | - const getFallbackLocale = computed((): string => unref(getLocale).fallback); | 18 | +// get Fallback Locales |
19 | +const getFallbackLocale = computed((): string => unref(getLocale).fallback); | ||
21 | 20 | ||
22 | - const getShowLocale = computed(() => unref(getLocale).show); | 21 | +const getShowLocale = computed(() => unref(getLocale).show); |
23 | 22 | ||
24 | - // Set locale configuration | ||
25 | - function setLocale(locale: Partial<LocaleSetting>): void { | ||
26 | - appStore.commitProjectConfigState({ locale }); | ||
27 | - } | 23 | +// Set locale configuration |
24 | +function setLocale(locale: Partial<LocaleSetting>): void { | ||
25 | + appStore.commitProjectConfigState({ locale }); | ||
26 | +} | ||
28 | 27 | ||
28 | +export function useLocaleSetting() { | ||
29 | return { | 29 | return { |
30 | getLocale, | 30 | getLocale, |
31 | getLang, | 31 | getLang, |
src/hooks/setting/useMenuSetting.ts
@@ -7,89 +7,89 @@ import { appStore } from '/@/store/modules/app'; | @@ -7,89 +7,89 @@ import { appStore } from '/@/store/modules/app'; | ||
7 | import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; | 7 | import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; |
8 | import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; | 8 | import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; |
9 | 9 | ||
10 | -export function useMenuSetting() { | ||
11 | - // Get menu configuration | ||
12 | - const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting); | 10 | +// Get menu configuration |
11 | +const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting); | ||
13 | 12 | ||
14 | - const getCollapsed = computed(() => unref(getMenuSetting).collapsed); | 13 | +const getCollapsed = computed(() => unref(getMenuSetting).collapsed); |
15 | 14 | ||
16 | - const getMenuType = computed(() => unref(getMenuSetting).type); | 15 | +const getMenuType = computed(() => unref(getMenuSetting).type); |
17 | 16 | ||
18 | - const getMenuMode = computed(() => unref(getMenuSetting).mode); | 17 | +const getMenuMode = computed(() => unref(getMenuSetting).mode); |
19 | 18 | ||
20 | - const getMenuFixed = computed(() => unref(getMenuSetting).fixed); | 19 | +const getMenuFixed = computed(() => unref(getMenuSetting).fixed); |
21 | 20 | ||
22 | - const getShowMenu = computed(() => unref(getMenuSetting).show); | 21 | +const getShowMenu = computed(() => unref(getMenuSetting).show); |
23 | 22 | ||
24 | - const getMenuHidden = computed(() => unref(getMenuSetting).hidden); | 23 | +const getMenuHidden = computed(() => unref(getMenuSetting).hidden); |
25 | 24 | ||
26 | - const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth); | 25 | +const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth); |
27 | 26 | ||
28 | - const getTrigger = computed(() => unref(getMenuSetting).trigger); | 27 | +const getTrigger = computed(() => unref(getMenuSetting).trigger); |
29 | 28 | ||
30 | - const getMenuTheme = computed(() => unref(getMenuSetting).theme); | 29 | +const getMenuTheme = computed(() => unref(getMenuSetting).theme); |
31 | 30 | ||
32 | - const getSplit = computed(() => unref(getMenuSetting).split); | 31 | +const getSplit = computed(() => unref(getMenuSetting).split); |
33 | 32 | ||
34 | - const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor); | 33 | +const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor); |
35 | 34 | ||
36 | - const getCanDrag = computed(() => unref(getMenuSetting).canDrag); | 35 | +const getCanDrag = computed(() => unref(getMenuSetting).canDrag); |
37 | 36 | ||
38 | - const getAccordion = computed(() => unref(getMenuSetting).accordion); | 37 | +const getAccordion = computed(() => unref(getMenuSetting).accordion); |
39 | 38 | ||
40 | - const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle); | 39 | +const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle); |
41 | 40 | ||
42 | - const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign); | 41 | +const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign); |
43 | 42 | ||
44 | - const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR); | 43 | +const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR); |
45 | 44 | ||
46 | - const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU); | 45 | +const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU); |
47 | 46 | ||
48 | - const getShowTopMenu = computed(() => { | ||
49 | - return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); | ||
50 | - }); | 47 | +const getShowTopMenu = computed(() => { |
48 | + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); | ||
49 | +}); | ||
51 | 50 | ||
52 | - const getShowHeaderTrigger = computed(() => { | ||
53 | - if ( | ||
54 | - unref(getMenuType) === MenuTypeEnum.TOP_MENU || | ||
55 | - !unref(getShowMenu) || | ||
56 | - !unref(getMenuHidden) | ||
57 | - ) { | ||
58 | - return false; | ||
59 | - } | 51 | +const getShowHeaderTrigger = computed(() => { |
52 | + if ( | ||
53 | + unref(getMenuType) === MenuTypeEnum.TOP_MENU || | ||
54 | + !unref(getShowMenu) || | ||
55 | + !unref(getMenuHidden) | ||
56 | + ) { | ||
57 | + return false; | ||
58 | + } | ||
60 | 59 | ||
61 | - return unref(getTrigger) === TriggerEnum.HEADER; | ||
62 | - }); | 60 | + return unref(getTrigger) === TriggerEnum.HEADER; |
61 | +}); | ||
63 | 62 | ||
64 | - const getIsHorizontal = computed(() => { | ||
65 | - return unref(getMenuMode) === MenuModeEnum.HORIZONTAL; | ||
66 | - }); | 63 | +const getIsHorizontal = computed(() => { |
64 | + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL; | ||
65 | +}); | ||
67 | 66 | ||
68 | - const getRealWidth = computed(() => { | ||
69 | - return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); | ||
70 | - }); | 67 | +const getRealWidth = computed(() => { |
68 | + return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); | ||
69 | +}); | ||
71 | 70 | ||
72 | - const getMiniWidthNumber = computed(() => { | ||
73 | - const { collapsedShowTitle } = unref(getMenuSetting); | ||
74 | - return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; | ||
75 | - }); | 71 | +const getMiniWidthNumber = computed(() => { |
72 | + const { collapsedShowTitle } = unref(getMenuSetting); | ||
73 | + return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; | ||
74 | +}); | ||
76 | 75 | ||
77 | - const getCalcContentWidth = computed(() => { | ||
78 | - const width = unref(getIsTopMenu) || !unref(getShowMenu) ? 0 : unref(getRealWidth); | ||
79 | - return `calc(100% - ${unref(width)}px)`; | ||
80 | - }); | 76 | +const getCalcContentWidth = computed(() => { |
77 | + const width = unref(getIsTopMenu) || !unref(getShowMenu) ? 0 : unref(getRealWidth); | ||
78 | + return `calc(100% - ${unref(width)}px)`; | ||
79 | +}); | ||
81 | 80 | ||
82 | - // Set menu configuration | ||
83 | - function setMenuSetting(menuSetting: Partial<MenuSetting>): void { | ||
84 | - appStore.commitProjectConfigState({ menuSetting }); | ||
85 | - } | 81 | +// Set menu configuration |
82 | +function setMenuSetting(menuSetting: Partial<MenuSetting>): void { | ||
83 | + appStore.commitProjectConfigState({ menuSetting }); | ||
84 | +} | ||
86 | 85 | ||
87 | - function toggleCollapsed() { | ||
88 | - setMenuSetting({ | ||
89 | - collapsed: !unref(getCollapsed), | ||
90 | - }); | ||
91 | - } | 86 | +function toggleCollapsed() { |
87 | + setMenuSetting({ | ||
88 | + collapsed: !unref(getCollapsed), | ||
89 | + }); | ||
90 | +} | ||
92 | 91 | ||
92 | +export function useMenuSetting() { | ||
93 | return { | 93 | return { |
94 | setMenuSetting, | 94 | setMenuSetting, |
95 | 95 |
src/hooks/setting/useMultipleTabSetting.ts
@@ -4,17 +4,17 @@ import { computed, unref } from 'vue'; | @@ -4,17 +4,17 @@ import { computed, unref } from 'vue'; | ||
4 | 4 | ||
5 | import { appStore } from '/@/store/modules/app'; | 5 | import { appStore } from '/@/store/modules/app'; |
6 | 6 | ||
7 | -export function useMultipleTabSetting() { | ||
8 | - const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting); | 7 | +const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting); |
9 | 8 | ||
10 | - const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show); | 9 | +const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show); |
11 | 10 | ||
12 | - const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick); | 11 | +const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick); |
13 | 12 | ||
14 | - function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { | ||
15 | - appStore.commitProjectConfigState({ multiTabsSetting }); | ||
16 | - } | 13 | +function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { |
14 | + appStore.commitProjectConfigState({ multiTabsSetting }); | ||
15 | +} | ||
17 | 16 | ||
17 | +export function useMultipleTabSetting() { | ||
18 | return { | 18 | return { |
19 | setMultipleTabSetting, | 19 | setMultipleTabSetting, |
20 | 20 |
src/hooks/setting/useRootSetting.ts
@@ -9,47 +9,48 @@ type RootSetting = Omit< | @@ -9,47 +9,48 @@ type RootSetting = Omit< | ||
9 | ProjectConfig, | 9 | ProjectConfig, |
10 | 'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting' | 10 | 'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting' |
11 | >; | 11 | >; |
12 | -export function useRootSetting() { | ||
13 | - const getRootSetting = computed((): RootSetting => appStore.getProjectConfig); | ||
14 | 12 | ||
15 | - const getPageLoading = computed(() => appStore.getPageLoading); | 13 | +const getRootSetting = computed((): RootSetting => appStore.getProjectConfig); |
14 | + | ||
15 | +const getPageLoading = computed(() => appStore.getPageLoading); | ||
16 | 16 | ||
17 | - const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive); | 17 | +const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive); |
18 | 18 | ||
19 | - const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage); | 19 | +const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage); |
20 | 20 | ||
21 | - const getPermissionMode = computed(() => unref(getRootSetting).permissionMode); | 21 | +const getPermissionMode = computed(() => unref(getRootSetting).permissionMode); |
22 | 22 | ||
23 | - const getShowLogo = computed(() => unref(getRootSetting).showLogo); | 23 | +const getShowLogo = computed(() => unref(getRootSetting).showLogo); |
24 | 24 | ||
25 | - const getContentMode = computed(() => unref(getRootSetting).contentMode); | 25 | +const getContentMode = computed(() => unref(getRootSetting).contentMode); |
26 | 26 | ||
27 | - const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop); | 27 | +const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop); |
28 | 28 | ||
29 | - const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton); | 29 | +const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton); |
30 | 30 | ||
31 | - const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle); | 31 | +const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle); |
32 | 32 | ||
33 | - const getShowFooter = computed(() => unref(getRootSetting).showFooter); | 33 | +const getShowFooter = computed(() => unref(getRootSetting).showFooter); |
34 | 34 | ||
35 | - const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb); | 35 | +const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb); |
36 | 36 | ||
37 | - const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon); | 37 | +const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon); |
38 | 38 | ||
39 | - const getFullContent = computed(() => unref(getRootSetting).fullContent); | 39 | +const getFullContent = computed(() => unref(getRootSetting).fullContent); |
40 | 40 | ||
41 | - const getColorWeak = computed(() => unref(getRootSetting).colorWeak); | 41 | +const getColorWeak = computed(() => unref(getRootSetting).colorWeak); |
42 | 42 | ||
43 | - const getGrayMode = computed(() => unref(getRootSetting).grayMode); | 43 | +const getGrayMode = computed(() => unref(getRootSetting).grayMode); |
44 | 44 | ||
45 | - const getLayoutContentMode = computed(() => | ||
46 | - unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED | ||
47 | - ); | 45 | +const getLayoutContentMode = computed(() => |
46 | + unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED | ||
47 | +); | ||
48 | 48 | ||
49 | - function setRootSetting(setting: Partial<RootSetting>) { | ||
50 | - appStore.commitProjectConfigState(setting); | ||
51 | - } | 49 | +function setRootSetting(setting: Partial<RootSetting>) { |
50 | + appStore.commitProjectConfigState(setting); | ||
51 | +} | ||
52 | 52 | ||
53 | +export function useRootSetting() { | ||
53 | return { | 54 | return { |
54 | setRootSetting, | 55 | setRootSetting, |
55 | 56 |
src/hooks/setting/useTransitionSetting.ts
@@ -4,23 +4,23 @@ import { computed, unref } from 'vue'; | @@ -4,23 +4,23 @@ import { computed, unref } from 'vue'; | ||
4 | 4 | ||
5 | import { appStore } from '/@/store/modules/app'; | 5 | import { appStore } from '/@/store/modules/app'; |
6 | 6 | ||
7 | -export function useTransitionSetting() { | ||
8 | - const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting); | 7 | +const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting); |
9 | 8 | ||
10 | - const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable); | 9 | +const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable); |
11 | 10 | ||
12 | - const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress); | 11 | +const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress); |
13 | 12 | ||
14 | - const getOpenPageLoading = computed((): boolean => { | ||
15 | - return !!unref(getTransitionSetting)?.openPageLoading; | ||
16 | - }); | 13 | +const getOpenPageLoading = computed((): boolean => { |
14 | + return !!unref(getTransitionSetting)?.openPageLoading; | ||
15 | +}); | ||
17 | 16 | ||
18 | - const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition); | 17 | +const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition); |
19 | 18 | ||
20 | - function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) { | ||
21 | - appStore.commitProjectConfigState({ transitionSetting }); | ||
22 | - } | 19 | +function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) { |
20 | + appStore.commitProjectConfigState({ transitionSetting }); | ||
21 | +} | ||
23 | 22 | ||
23 | +export function useTransitionSetting() { | ||
24 | return { | 24 | return { |
25 | setTransitionSetting, | 25 | setTransitionSetting, |
26 | 26 |
src/hooks/web/useDesign.ts
1 | import { useAppProviderContext } from '/@/components/Application'; | 1 | import { useAppProviderContext } from '/@/components/Application'; |
2 | -import { computed } from 'vue'; | ||
3 | -// import { useCssModule, reactive } from 'vue'; | 2 | +// import { computed } from 'vue'; |
3 | +// import { lowerFirst } from 'lodash-es'; | ||
4 | export function useDesign(scope: string) { | 4 | export function useDesign(scope: string) { |
5 | const values = useAppProviderContext(); | 5 | const values = useAppProviderContext(); |
6 | - // const style = cssModule ? useCssModule() : {}; | 6 | + // const $style = cssModule ? useCssModule() : {}; |
7 | 7 | ||
8 | + // const style: Record<string, string> = {}; | ||
8 | // if (cssModule) { | 9 | // if (cssModule) { |
9 | - // Object.keys(style).forEach((key) => { | ||
10 | - // const moduleCls = style[key]; | ||
11 | - // style[key] = `${cls}-${moduleCls}`; | 10 | + // Object.keys($style).forEach((key) => { |
11 | + // // const moduleCls = $style[key]; | ||
12 | + // const k = key.replace(new RegExp(`^${values.prefixCls}-?`, 'ig'), ''); | ||
13 | + // style[lowerFirst(k)] = $style[key]; | ||
12 | // }); | 14 | // }); |
13 | // } | 15 | // } |
14 | return { | 16 | return { |
15 | - prefixCls: computed(() => `${values.prefixCls}-${scope}`), | 17 | + // prefixCls: computed(() => `${values.prefixCls}-${scope}`), |
18 | + prefixCls: `${values.prefixCls}-${scope}`, | ||
16 | prefixVar: values.prefixCls, | 19 | prefixVar: values.prefixCls, |
17 | // style, | 20 | // style, |
18 | }; | 21 | }; |
src/hooks/web/useFullContent.ts
@@ -2,12 +2,12 @@ import { computed, unref } from 'vue'; | @@ -2,12 +2,12 @@ import { computed, unref } from 'vue'; | ||
2 | 2 | ||
3 | import { appStore } from '/@/store/modules/app'; | 3 | import { appStore } from '/@/store/modules/app'; |
4 | 4 | ||
5 | -import { useRouter } from 'vue-router'; | 5 | +import router from '/@/router'; |
6 | /** | 6 | /** |
7 | * @description: Full screen display content | 7 | * @description: Full screen display content |
8 | */ | 8 | */ |
9 | export const useFullContent = () => { | 9 | export const useFullContent = () => { |
10 | - const { currentRoute } = useRouter(); | 10 | + const { currentRoute } = router; |
11 | 11 | ||
12 | // Whether to display the content in full screen without displaying the menu | 12 | // Whether to display the content in full screen without displaying the menu |
13 | const getFullContent = computed(() => { | 13 | const getFullContent = computed(() => { |
src/hooks/web/usePage.ts
1 | -import { appStore } from '/@/store/modules/app'; | ||
2 | import type { RouteLocationRaw } from 'vue-router'; | 1 | import type { RouteLocationRaw } from 'vue-router'; |
3 | 2 | ||
4 | import { PageEnum } from '/@/enums/pageEnum'; | 3 | import { PageEnum } from '/@/enums/pageEnum'; |
@@ -11,7 +10,6 @@ export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEn | @@ -11,7 +10,6 @@ export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEn | ||
11 | 10 | ||
12 | function handleError(e: Error) { | 11 | function handleError(e: Error) { |
13 | console.error(e); | 12 | console.error(e); |
14 | - appStore.commitPageLoadingState(false); | ||
15 | } | 13 | } |
16 | 14 | ||
17 | // page switch | 15 | // page switch |
src/layouts/default/header/LayoutHeader.tsx
@@ -80,13 +80,7 @@ export default defineComponent({ | @@ -80,13 +80,7 @@ export default defineComponent({ | ||
80 | const { refreshPage } = useTabs(); | 80 | const { refreshPage } = useTabs(); |
81 | const { t } = useI18n(); | 81 | const { t } = useI18n(); |
82 | 82 | ||
83 | - const { | ||
84 | - getShowTopMenu, | ||
85 | - getShowHeaderTrigger, | ||
86 | - getSplit, | ||
87 | - getTopMenuAlign, | ||
88 | - getIsHorizontal, | ||
89 | - } = useMenuSetting(); | 83 | + const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsHorizontal } = useMenuSetting(); |
90 | 84 | ||
91 | const { getShowLocale } = useLocaleSetting(); | 85 | const { getShowLocale } = useLocaleSetting(); |
92 | const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting(); | 86 | const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting(); |
@@ -184,7 +178,7 @@ export default defineComponent({ | @@ -184,7 +178,7 @@ export default defineComponent({ | ||
184 | {/* <div class={[`layout-header__menu `]}> */} | 178 | {/* <div class={[`layout-header__menu `]}> */} |
185 | <LayoutMenu | 179 | <LayoutMenu |
186 | isHorizontal={true} | 180 | isHorizontal={true} |
187 | - class={`justify-${unref(getTopMenuAlign)}`} | 181 | + // class={`justify-${unref(getTopMenuAlign)}`} |
188 | theme={unref(getHeaderTheme)} | 182 | theme={unref(getHeaderTheme)} |
189 | splitType={unref(getSplitType)} | 183 | splitType={unref(getSplitType)} |
190 | menuMode={unref(getMenuMode)} | 184 | menuMode={unref(getMenuMode)} |
src/layouts/default/header/LayoutMultipleHeader.tsx
@@ -21,7 +21,7 @@ export default defineComponent({ | @@ -21,7 +21,7 @@ export default defineComponent({ | ||
21 | 21 | ||
22 | const injectValue = useLayoutContext(); | 22 | const injectValue = useLayoutContext(); |
23 | 23 | ||
24 | - const { getCalcContentWidth } = useMenuSetting(); | 24 | + const { getCalcContentWidth, getSplit } = useMenuSetting(); |
25 | 25 | ||
26 | const { | 26 | const { |
27 | getFixed, | 27 | getFixed, |
@@ -56,7 +56,8 @@ export default defineComponent({ | @@ -56,7 +56,8 @@ export default defineComponent({ | ||
56 | (): CSSProperties => { | 56 | (): CSSProperties => { |
57 | const style: CSSProperties = {}; | 57 | const style: CSSProperties = {}; |
58 | if (unref(getFixed)) { | 58 | if (unref(getFixed)) { |
59 | - style.width = unref(injectValue.isMobile) ? '100%' : unref(getCalcContentWidth); | 59 | + style.width = |
60 | + unref(injectValue.isMobile) || unref(getSplit) ? '100%' : unref(getCalcContentWidth); | ||
60 | } | 61 | } |
61 | if (unref(getShowFullHeaderRef)) { | 62 | if (unref(getShowFullHeaderRef)) { |
62 | style.top = `${unref(fullHeaderHeightRef)}px`; | 63 | style.top = `${unref(fullHeaderHeightRef)}px`; |
src/layouts/default/menu/index.tsx
1 | import './index.less'; | 1 | import './index.less'; |
2 | 2 | ||
3 | import { PropType, toRef } from 'vue'; | 3 | import { PropType, toRef } from 'vue'; |
4 | -import type { Menu } from '/@/router/types'; | ||
5 | 4 | ||
6 | import { computed, defineComponent, unref } from 'vue'; | 5 | import { computed, defineComponent, unref } from 'vue'; |
7 | -import { BasicMenu } from '/@/components/Menu/index'; | 6 | +import { BasicMenu } from '/@/components/Menu'; |
8 | import { AppLogo } from '/@/components/Application'; | 7 | import { AppLogo } from '/@/components/Application'; |
9 | 8 | ||
10 | import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; | 9 | import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; |
11 | 10 | ||
12 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 11 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
13 | -import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
14 | 12 | ||
15 | import { useGo } from '/@/hooks/web/usePage'; | 13 | import { useGo } from '/@/hooks/web/usePage'; |
16 | import { useSplitMenu } from './useLayoutMenu'; | 14 | import { useSplitMenu } from './useLayoutMenu'; |
17 | import { openWindow } from '/@/utils'; | 15 | import { openWindow } from '/@/utils'; |
18 | import { propTypes } from '/@/utils/propTypes'; | 16 | import { propTypes } from '/@/utils/propTypes'; |
17 | +import { isUrl } from '/@/utils/is'; | ||
18 | +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
19 | 19 | ||
20 | export default defineComponent({ | 20 | export default defineComponent({ |
21 | name: 'LayoutMenu', | 21 | name: 'LayoutMenu', |
@@ -38,56 +38,46 @@ export default defineComponent({ | @@ -38,56 +38,46 @@ export default defineComponent({ | ||
38 | const go = useGo(); | 38 | const go = useGo(); |
39 | 39 | ||
40 | const { | 40 | const { |
41 | - setMenuSetting, | ||
42 | getMenuMode, | 41 | getMenuMode, |
43 | getMenuType, | 42 | getMenuType, |
44 | getCollapsedShowTitle, | 43 | getCollapsedShowTitle, |
45 | - getIsSidebarType, | ||
46 | getMenuTheme, | 44 | getMenuTheme, |
47 | getCollapsed, | 45 | getCollapsed, |
48 | getAccordion, | 46 | getAccordion, |
47 | + getIsSidebarType, | ||
49 | } = useMenuSetting(); | 48 | } = useMenuSetting(); |
50 | - | ||
51 | const { getShowLogo } = useRootSetting(); | 49 | const { getShowLogo } = useRootSetting(); |
52 | 50 | ||
53 | - const { flatMenusRef, menusRef } = useSplitMenu(toRef(props, 'splitType')); | ||
54 | - | ||
55 | - const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType)); | 51 | + const { menusRef } = useSplitMenu(toRef(props, 'splitType')); |
56 | 52 | ||
57 | const getComputedMenuMode = computed(() => props.menuMode || unref(getMenuMode)); | 53 | const getComputedMenuMode = computed(() => props.menuMode || unref(getMenuMode)); |
58 | 54 | ||
59 | const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme)); | 55 | const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme)); |
60 | - | 56 | + const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType)); |
61 | const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP); | 57 | const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP); |
62 | - | ||
63 | /** | 58 | /** |
64 | * click menu | 59 | * click menu |
65 | * @param menu | 60 | * @param menu |
66 | */ | 61 | */ |
67 | - function handleMenuClick(menu: Menu) { | ||
68 | - go(menu.path); | 62 | + function handleMenuClick(path: string) { |
63 | + go(path); | ||
69 | } | 64 | } |
70 | 65 | ||
71 | /** | 66 | /** |
72 | * before click menu | 67 | * before click menu |
73 | * @param menu | 68 | * @param menu |
74 | */ | 69 | */ |
75 | - async function beforeMenuClickFn(menu: Menu) { | ||
76 | - const { meta: { externalLink } = {} } = menu; | ||
77 | - | ||
78 | - if (externalLink) { | ||
79 | - openWindow(externalLink); | ||
80 | - return false; | 70 | + async function beforeMenuClickFn(path: string) { |
71 | + if (!isUrl(path)) { | ||
72 | + return true; | ||
81 | } | 73 | } |
82 | - return true; | ||
83 | - } | ||
84 | - | ||
85 | - function handleClickSearchInput() { | ||
86 | - unref(getCollapsed) && setMenuSetting({ collapsed: false }); | 74 | + openWindow(path); |
75 | + return false; | ||
87 | } | 76 | } |
88 | 77 | ||
89 | function renderHeader() { | 78 | function renderHeader() { |
90 | if (!unref(showLogo)) return null; | 79 | if (!unref(showLogo)) return null; |
80 | + | ||
91 | return ( | 81 | return ( |
92 | <AppLogo | 82 | <AppLogo |
93 | showTitle={!unref(getCollapsed)} | 83 | showTitle={!unref(getCollapsed)} |
@@ -100,20 +90,17 @@ export default defineComponent({ | @@ -100,20 +90,17 @@ export default defineComponent({ | ||
100 | return () => { | 90 | return () => { |
101 | return ( | 91 | return ( |
102 | <BasicMenu | 92 | <BasicMenu |
103 | - class="layout-menu" | ||
104 | beforeClickFn={beforeMenuClickFn} | 93 | beforeClickFn={beforeMenuClickFn} |
105 | isHorizontal={props.isHorizontal} | 94 | isHorizontal={props.isHorizontal} |
106 | - appendClass={unref(appendClass)} | ||
107 | type={unref(getMenuType)} | 95 | type={unref(getMenuType)} |
108 | mode={unref(getComputedMenuMode)} | 96 | mode={unref(getComputedMenuMode)} |
109 | collapsedShowTitle={unref(getCollapsedShowTitle)} | 97 | collapsedShowTitle={unref(getCollapsedShowTitle)} |
110 | theme={unref(getComputedMenuTheme)} | 98 | theme={unref(getComputedMenuTheme)} |
111 | - showLogo={unref(showLogo)} | ||
112 | items={unref(menusRef)} | 99 | items={unref(menusRef)} |
113 | - flatItems={unref(flatMenusRef)} | ||
114 | accordion={unref(getAccordion)} | 100 | accordion={unref(getAccordion)} |
115 | onMenuClick={handleMenuClick} | 101 | onMenuClick={handleMenuClick} |
116 | - onClickSearchInput={handleClickSearchInput} | 102 | + appendClass={unref(appendClass)} |
103 | + showLogo={unref(showLogo)} | ||
117 | > | 104 | > |
118 | {{ | 105 | {{ |
119 | header: () => renderHeader(), | 106 | header: () => renderHeader(), |
src/layouts/default/menu/useLayoutMenu.ts
@@ -8,24 +8,12 @@ import { MenuSplitTyeEnum } from '/@/enums/menuEnum'; | @@ -8,24 +8,12 @@ import { MenuSplitTyeEnum } from '/@/enums/menuEnum'; | ||
8 | import { useThrottle } from '/@/hooks/core/useThrottle'; | 8 | import { useThrottle } from '/@/hooks/core/useThrottle'; |
9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | 9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
10 | 10 | ||
11 | -import { | ||
12 | - getChildrenMenus, | ||
13 | - getCurrentParentPath, | ||
14 | - getFlatChildrenMenus, | ||
15 | - getFlatMenus, | ||
16 | - getMenus, | ||
17 | - getShallowMenus, | ||
18 | -} from '/@/router/menus'; | 11 | +import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus'; |
19 | import { permissionStore } from '/@/store/modules/permission'; | 12 | import { permissionStore } from '/@/store/modules/permission'; |
20 | -// import { useI18n } from '/@/hooks/web/useI18n'; | ||
21 | -// import { cloneDeep } from 'lodash-es'; | ||
22 | 13 | ||
23 | -// const { t } = useI18n(); | ||
24 | export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | 14 | export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { |
25 | // Menu array | 15 | // Menu array |
26 | const menusRef = ref<Menu[]>([]); | 16 | const menusRef = ref<Menu[]>([]); |
27 | - // flat menu array | ||
28 | - const flatMenusRef = ref<Menu[]>([]); | ||
29 | 17 | ||
30 | const { currentRoute } = useRouter(); | 18 | const { currentRoute } = useRouter(); |
31 | 19 | ||
@@ -45,14 +33,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | @@ -45,14 +33,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | ||
45 | return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit); | 33 | return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit); |
46 | }); | 34 | }); |
47 | 35 | ||
48 | - // const getI18nFlatMenus = computed(() => { | ||
49 | - // return setI18nName(flatMenusRef.value, true, false); | ||
50 | - // }); | ||
51 | - | ||
52 | - // const getI18nMenus = computed(() => { | ||
53 | - // return setI18nName(menusRef.value, true, true); | ||
54 | - // }); | ||
55 | - | ||
56 | watch( | 36 | watch( |
57 | [() => unref(currentRoute).path, () => unref(splitType)], | 37 | [() => unref(currentRoute).path, () => unref(splitType)], |
58 | async ([path]: [string, MenuSplitTyeEnum]) => { | 38 | async ([path]: [string, MenuSplitTyeEnum]) => { |
@@ -83,20 +63,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | @@ -83,20 +63,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | ||
83 | genMenus(); | 63 | genMenus(); |
84 | }); | 64 | }); |
85 | 65 | ||
86 | - // function setI18nName(list: Menu[], clone = false, deep = true) { | ||
87 | - // const menus = clone ? cloneDeep(list) : list; | ||
88 | - // const arr: Menu[] = []; | ||
89 | - // menus.forEach((item) => { | ||
90 | - // if (!item.name.includes('.')) return; | ||
91 | - // item.name = t(item.name); | ||
92 | - | ||
93 | - // if (item.children && deep) { | ||
94 | - // setI18nName(item.children, false, deep); | ||
95 | - // } | ||
96 | - // }); | ||
97 | - // return menus; | ||
98 | - // } | ||
99 | - | ||
100 | // Handle left menu split | 66 | // Handle left menu split |
101 | async function handleSplitLeftMenu(parentPath: string) { | 67 | async function handleSplitLeftMenu(parentPath: string) { |
102 | if (unref(splitLeft)) return; | 68 | if (unref(splitLeft)) return; |
@@ -105,14 +71,11 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | @@ -105,14 +71,11 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | ||
105 | const children = await getChildrenMenus(parentPath); | 71 | const children = await getChildrenMenus(parentPath); |
106 | if (!children) { | 72 | if (!children) { |
107 | setMenuSetting({ hidden: false }); | 73 | setMenuSetting({ hidden: false }); |
108 | - flatMenusRef.value = []; | ||
109 | menusRef.value = []; | 74 | menusRef.value = []; |
110 | return; | 75 | return; |
111 | } | 76 | } |
112 | 77 | ||
113 | - const flatChildren = await getFlatChildrenMenus(children); | ||
114 | setMenuSetting({ hidden: true }); | 78 | setMenuSetting({ hidden: true }); |
115 | - flatMenusRef.value = flatChildren; | ||
116 | menusRef.value = children; | 79 | menusRef.value = children; |
117 | } | 80 | } |
118 | 81 | ||
@@ -120,7 +83,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | @@ -120,7 +83,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | ||
120 | async function genMenus() { | 83 | async function genMenus() { |
121 | // normal mode | 84 | // normal mode |
122 | if (unref(normalType)) { | 85 | if (unref(normalType)) { |
123 | - flatMenusRef.value = await getFlatMenus(); | ||
124 | menusRef.value = await getMenus(); | 86 | menusRef.value = await getMenus(); |
125 | return; | 87 | return; |
126 | } | 88 | } |
@@ -129,11 +91,10 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | @@ -129,11 +91,10 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { | ||
129 | if (unref(spiltTop)) { | 91 | if (unref(spiltTop)) { |
130 | const shallowMenus = await getShallowMenus(); | 92 | const shallowMenus = await getShallowMenus(); |
131 | 93 | ||
132 | - flatMenusRef.value = shallowMenus; | ||
133 | menusRef.value = shallowMenus; | 94 | menusRef.value = shallowMenus; |
134 | return; | 95 | return; |
135 | } | 96 | } |
136 | } | 97 | } |
137 | 98 | ||
138 | - return { flatMenusRef, menusRef }; | 99 | + return { menusRef }; |
139 | } | 100 | } |
src/layouts/default/sider/index.less
@@ -12,10 +12,25 @@ | @@ -12,10 +12,25 @@ | ||
12 | 12 | ||
13 | &.ant-layout-sider-dark { | 13 | &.ant-layout-sider-dark { |
14 | background: @sider-dark-bg-color; | 14 | background: @sider-dark-bg-color; |
15 | + | ||
16 | + .ant-layout-sider-trigger { | ||
17 | + color: darken(@white, 25%); | ||
18 | + background: @trigger-dark-bg-color; | ||
19 | + | ||
20 | + &:hover { | ||
21 | + color: @white; | ||
22 | + background: @trigger-dark-hover-bg-color; | ||
23 | + } | ||
24 | + } | ||
15 | } | 25 | } |
16 | 26 | ||
17 | &:not(.ant-layout-sider-dark) { | 27 | &:not(.ant-layout-sider-dark) { |
18 | box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05); | 28 | box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05); |
29 | + | ||
30 | + .ant-layout-sider-trigger { | ||
31 | + color: @text-color-base; | ||
32 | + border-top: 1px solid @border-color-light; | ||
33 | + } | ||
19 | } | 34 | } |
20 | 35 | ||
21 | .ant-layout-sider-zero-width-trigger { | 36 | .ant-layout-sider-zero-width-trigger { |
@@ -43,9 +58,9 @@ | @@ -43,9 +58,9 @@ | ||
43 | box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15); | 58 | box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15); |
44 | } | 59 | } |
45 | } | 60 | } |
46 | -} | ||
47 | 61 | ||
48 | -.ant-layout-sider-trigger { | ||
49 | - height: 36px; | ||
50 | - line-height: 36px; | 62 | + & .ant-layout-sider-trigger { |
63 | + height: 36px; | ||
64 | + line-height: 36px; | ||
65 | + } | ||
51 | } | 66 | } |
src/layouts/default/sider/index.tsx
@@ -100,7 +100,7 @@ export default defineComponent({ | @@ -100,7 +100,7 @@ export default defineComponent({ | ||
100 | flex: `0 0 ${width}`, | 100 | flex: `0 0 ${width}`, |
101 | maxWidth: width, | 101 | maxWidth: width, |
102 | minWidth: width, | 102 | minWidth: width, |
103 | - transition: 'all 0.2s', | 103 | + transition: 'all 0.15s', |
104 | }; | 104 | }; |
105 | } | 105 | } |
106 | ); | 106 | ); |
@@ -126,7 +126,7 @@ export default defineComponent({ | @@ -126,7 +126,7 @@ export default defineComponent({ | ||
126 | )} | 126 | )} |
127 | <Layout.Sider | 127 | <Layout.Sider |
128 | ref={sideRef} | 128 | ref={sideRef} |
129 | - breakpoint="md" | 129 | + breakpoint="lg" |
130 | collapsible | 130 | collapsible |
131 | class={unref(getSiderClass)} | 131 | class={unref(getSiderClass)} |
132 | style={unref(getSiderStyle)} | 132 | style={unref(getSiderStyle)} |
src/utils/is.ts
@@ -79,3 +79,8 @@ export const isMobile = (): boolean => { | @@ -79,3 +79,8 @@ export const isMobile = (): boolean => { | ||
79 | /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i | 79 | /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i |
80 | ); | 80 | ); |
81 | }; | 81 | }; |
82 | + | ||
83 | +export const isUrl = (path: string): boolean => { | ||
84 | + const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; | ||
85 | + return reg.test(path); | ||
86 | +}; |