Commit 88f4a3f02a0c0f35953c93427fe700d414b6ec50

Authored by vben
1 parent 74e62cbc

perf: perf menu

src/components/Application/src/AppLocalePicker.vue
... ... @@ -8,10 +8,10 @@
8 8 :dropMenuList="localeList"
9 9 :selectedKeys="selectedKeys"
10 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 15 <span v-if="showText">{{ getLangText }}</span>
16 16 </span>
17 17 </Dropdown>
... ... @@ -28,6 +28,7 @@
28 28 import { LocaleType } from '/@/locales/types';
29 29  
30 30 import { propTypes } from '/@/utils/propTypes';
  31 + import { useDesign } from '/@/hooks/web/useDesign';
31 32  
32 33 export default defineComponent({
33 34 name: 'AppLocalPicker',
... ... @@ -39,9 +40,12 @@
39 40 reload: propTypes.bool,
40 41 },
41 42 setup(props) {
42   - const { localeList } = useLocaleSetting();
43 43 const selectedKeys = ref<string[]>([]);
44 44  
  45 + const { prefixCls } = useDesign('app-locale-picker');
  46 +
  47 + const { localeList } = useLocaleSetting();
  48 +
45 49 const { changeLocale, getLang } = useLocale();
46 50  
47 51 const getLangText = computed(() => {
... ... @@ -64,19 +68,22 @@
64 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 74 </script>
71 75  
72 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 81 .ant-dropdown-menu-item {
75 82 min-width: 160px;
76 83 }
77 84 }
78 85  
79   - .app-local-picker {
  86 + .@{prefix-cls} {
80 87 display: flex;
81 88 align-items: center;
82 89 cursor: pointer;
... ...
src/components/Basic/src/BasicArrow.vue
... ... @@ -20,15 +20,17 @@
20 20 expand: propTypes.bool,
21 21 top: propTypes.bool,
22 22 bottom: propTypes.bool,
  23 + inset: propTypes.bool,
23 24 },
24 25 setup(props) {
25 26 const getClass = computed(() => {
26   - const { expand, top, bottom } = props;
  27 + const { expand, top, bottom, inset } = props;
27 28 return [
28 29 'base-arrow',
29 30 {
30 31 'base-arrow__active': expand,
31 32 top,
  33 + inset,
32 34 bottom,
33 35 },
34 36 ];
... ... @@ -47,6 +49,10 @@
47 49 transition: all 0.3s ease 0.1s;
48 50 transform-origin: center center;
49 51  
  52 + &.inset {
  53 + line-height: 0px;
  54 + }
  55 +
50 56 &__active {
51 57 transform: rotate(90deg);
52 58 }
... ...
src/components/Menu/src/BasicMenu.tsx
... ... @@ -9,14 +9,15 @@ import {
9 9 unref,
10 10 reactive,
11 11 watch,
12   - onMounted,
13   - ref,
14 12 toRefs,
15 13 ComputedRef,
  14 + ref,
  15 + CSSProperties,
16 16 } from 'vue';
17 17 import { Menu } from 'ant-design-vue';
18 18 import MenuContent from './MenuContent';
19 19 // import { ScrollContainer } from '/@/components/Container';
  20 +// import { BasicArrow } from '/@/components/Basic';
20 21  
21 22 import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
22 23 import { ThemeEnum } from '/@/enums/appEnum';
... ... @@ -29,18 +30,20 @@ import { useRouter } from &#39;vue-router&#39;;
29 30 import { isFunction } from '/@/utils/is';
30 31 import { getSlot } from '/@/utils/helper/tsxHelper';
31 32 import { menuHasChildren } from './helper';
32   -
33 33 import { getCurrentParentPath } from '/@/router/menus';
34 34  
35 35 import { basicProps } from './props';
36 36 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
37 37 import { REDIRECT_NAME } from '/@/router/constant';
  38 +import { tabStore } from '/@/store/modules/tab';
  39 +import { useDesign } from '/@/hooks/web/useDesign';
38 40 export default defineComponent({
39 41 name: 'BasicMenu',
40 42 props: basicProps,
41 43 emits: ['menuClick'],
42 44 setup(props, { slots, emit }) {
43 45 const currentParentPath = ref('');
  46 + const isClickGo = ref(false);
44 47  
45 48 const menuState = reactive<MenuState>({
46 49 defaultSelectedKeys: [],
... ... @@ -51,170 +54,184 @@ export default defineComponent({
51 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 66 menuState,
62 67 items,
63   - flatItems,
64 68 mode,
65 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 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 117 handleMenuChange();
112   - props.isHorizontal && appStore.getProjectConfig.menuSetting.split && getParentPath();
  118 + unref(getSplit) && getParentPath();
113 119 }
114 120 );
115 121  
116 122 watch(
117 123 () => props.items,
118 124 () => {
119   - if (props.items) {
120   - handleMenuChange();
121   - }
  125 + handleMenuChange();
122 126 },
123 127 {
124 128 immediate: true,
125 129 }
126 130 );
127 131  
  132 + getParentPath();
  133 +
128 134 async function getParentPath() {
129 135 const { appendClass } = props;
130 136 if (!appendClass) return '';
131 137 const parentPath = await getCurrentParentPath(unref(currentRoute).path);
  138 +
132 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 143 const { beforeClickFn } = props;
137 144 if (beforeClickFn && isFunction(beforeClickFn)) {
138   - const flag = await beforeClickFn(menu);
  145 + const flag = await beforeClickFn(key);
139 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 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 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 232 function renderMenu() {
210   - const isInline = props.mode === MenuModeEnum.INLINE;
211 233 const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState;
212 234  
213   - const inlineCollapsedObj = isInline
214   - ? {
215   - inlineCollapsed: unref(getCollapsed),
216   - }
217   - : {};
218 235 return (
219 236 <Menu
220 237 selectedKeys={selectedKeys}
... ... @@ -224,36 +241,25 @@ export default defineComponent({
224 241 inlineIndent={props.inlineIndent}
225 242 theme={unref(theme)}
226 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 251 </Menu>
238 252 );
239 253 }
240 254  
241   - onMounted(async () => {
242   - getParentPath();
243   - });
244   -
245 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 260 {renderMenu()}
255   - </section>
256   - </section>
  261 + </div>
  262 + </>
257 263 );
258 264 };
259 265 },
... ...
src/components/Menu/src/BasicMenu.vue deleted 100644 โ†’ 0
1   -<template>
2   - <div> </div>
3   -</template>
4   -<script lang="ts">
5   - import { defineComponent } from 'vue';
6   - export default defineComponent({
7   - setup() {
8   - return {};
9   - },
10   - });
11   -</script>
src/components/Menu/src/MenuContent.tsx
1 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 5 import { defineComponent } from 'vue';
5 6 import Icon from '/@/components/Icon/index';
6 7 import { useI18n } from '/@/hooks/web/useI18n';
  8 +import { useDesign } from '/@/hooks/web/useDesign';
  9 +
  10 +const { t } = useI18n();
7 11  
8 12 export default defineComponent({
9 13 name: 'MenuContent',
... ... @@ -12,12 +16,10 @@ export default defineComponent({
12 16 type: Object as PropType<MenuType>,
13 17 default: null,
14 18 },
15   -
16 19 showTitle: {
17 20 type: Boolean as PropType<boolean>,
18 21 default: true,
19 22 },
20   -
21 23 level: {
22 24 type: Number as PropType<number>,
23 25 default: 0,
... ... @@ -28,13 +30,32 @@ export default defineComponent({
28 30 },
29 31 },
30 32 setup(props) {
31   - const { t } = useI18n();
  33 + const { prefixCls } = useDesign('basic-menu');
32 34  
33 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 56 * @description: ๆธฒๆŸ“ๅ›พๆ ‡
36 57 */
37   - function renderIcon(icon: string) {
  58 + function renderIcon(icon?: string) {
38 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 66 const { tag } = item;
46 67 if (!tag) return null;
47 68  
48   - const { dot, content, type = 'error' } = tag;
  69 + const { dot, content } = tag;
49 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 75 return () => {
59   - if (!props.item) {
  76 + const { item } = props;
  77 + if (!item) {
60 78 return null;
61 79 }
62   - const { showTitle } = props;
63   - const { icon } = props.item;
  80 + const { icon } = item;
64 81 const name = unref(getI18nName);
65 82  
66   - const cls = showTitle ? ['show-title'] : ['basic-menu__name'];
67   -
68 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 88 {name}
74 89 {renderTag()}
75 90 </span>
76 91 }
77   - </>
  92 + </span>
78 93 );
79 94 };
80 95 },
... ...
src/components/Menu/src/index.less
1 1 @import (reference) '../../../design/index.less';
2 2  
  3 +@basic-menu-prefix-cls: ~'@{namespace}-basic-menu';
  4 +
3 5 .active-style() {
4 6 color: @white;
5 7 background: linear-gradient(
... ... @@ -16,21 +18,48 @@
16 18 }
17 19 }
18 20  
19   -.basic-menu {
  21 +.@{basic-menu-prefix-cls} {
20 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 41 // collapsed show title start
27   - .show-title {
  42 + &--show-title {
28 43 max-width: unset !important;
29 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 63 padding: 2px 0;
35 64 }
36 65  
... ... @@ -47,14 +76,23 @@
47 76 & > li > .ant-menu-submenu-title {
48 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 94 // scrollbar -s tart
57   - &__content {
  95 + &-wrapper {
58 96 /* ๆปšๅŠจๆงฝ */
59 97 &::-webkit-scrollbar {
60 98 width: 5px;
... ... @@ -75,8 +113,20 @@
75 113 background: @border-color-dark;
76 114 }
77 115 }
  116 +
78 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 130 &__sidebar-hor {
81 131 // overflow: hidden;
82 132  
... ... @@ -85,20 +135,13 @@
85 135 border: 0;
86 136 align-items: center;
87 137  
88   - .basic-menu-item__level1 {
  138 + .@{basic-menu-prefix-cls}-item__level1 {
89 139 margin-right: 2px;
90 140 }
91 141  
92 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 143 .ant-menu-item {
101   - &.basic-menu-item__level1 {
  144 + &.@{basic-menu-prefix-cls}-item__level1 {
102 145 height: @header-height;
103 146 line-height: @header-height;
104 147 }
... ... @@ -155,7 +198,7 @@
155 198 background: @top-menu-active-bg-color;
156 199 }
157 200  
158   - .basic-menu-item__level1 {
  201 + .@{basic-menu-prefix-cls}-item__level1 {
159 202 background: transparent;
160 203  
161 204 &.top-active-menu {
... ... @@ -172,7 +215,7 @@
172 215  
173 216 .ant-menu-item,
174 217 .ant-menu-submenu {
175   - &.basic-menu-item__level1,
  218 + &.@{basic-menu-prefix-cls}-item__level1,
176 219 .ant-menu-submenu-title {
177 220 height: @header-height;
178 221 line-height: @header-height;
... ... @@ -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 230 > div {
188 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 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 239 .ant-menu-sub.ant-menu-inline > .ant-menu-item,
197 240 .ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
198 241 height: @app-menu-item-height;
... ... @@ -200,28 +243,28 @@
200 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 247 height: @app-menu-item-height;
205 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 255 background: @sider-dark-bg-color;
213 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 264 color: @white;
222 265 }
223 266  
224   - .basic-menu-item__level1 {
  267 + .@{basic-menu-prefix-cls}-item__level1 {
225 268 background-color: @sider-dark-bg-color;
226 269  
227 270 > .ant-menu-sub > li {
... ... @@ -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 276 .ant-menu-sub {
234 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 281 background-color: @sider-dark-lighten-2-bg-color;
239 282  
240 283 .ant-menu-item {
... ... @@ -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 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 313 color: @primary-color;
275 314 }
276 315 }
277 316  
278   - // ๅ…ณ้”ฎๅญ—็š„้ขœ่‰ฒ
279   - &__keyword {
280   - color: lighten(@primary-color, 20%);
281   - }
282   -
283 317 // ๆฟ€ๆดป็š„ๅญ่œๅ•ๆ ทๅผ
284 318 .ant-menu-item.ant-menu-item-selected {
285 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 323 // Reset menu item row height
290 324 .ant-menu-item,
291 325 .ant-menu-sub.ant-menu-inline > .ant-menu-item,
... ... @@ -298,26 +332,40 @@
298 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 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 383 // collapsed show title end
356 384 .ant-menu-item,
357 385 .ant-menu-submenu-title {
358   - > .basic-menu__name {
  386 + > .@{basic-menu-prefix-cls}__name {
359 387 width: 100%;
360 388  
361   - .basic-menu__tag {
  389 + .@{basic-menu-prefix-cls}__tag {
362 390 float: right;
363 391 margin-top: @app-menu-item-height / 2;
364 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 8 type: Array as PropType<Menu[]>,
9 9 default: () => [],
10 10 },
11   - flatItems: {
12   - type: Array as PropType<Menu[]>,
13   - default: () => [],
14   - },
15 11 appendClass: {
16 12 type: Boolean as PropType<boolean>,
17 13 default: false,
18 14 },
  15 +
19 16 collapsedShowTitle: {
20 17 type: Boolean as PropType<boolean>,
21 18 default: false,
... ... @@ -31,6 +28,10 @@ export const basicProps = {
31 28 type: String as PropType<MenuModeEnum>,
32 29 default: MenuModeEnum.INLINE,
33 30 },
  31 + showLogo: {
  32 + type: Boolean as PropType<boolean>,
  33 + default: false,
  34 + },
34 35 type: {
35 36 type: String as PropType<MenuTypeEnum>,
36 37 default: MenuTypeEnum.MIX,
... ... @@ -39,10 +40,6 @@ export const basicProps = {
39 40 type: String as PropType<string>,
40 41 default: ThemeEnum.DARK,
41 42 },
42   - showLogo: {
43   - type: Boolean as PropType<boolean>,
44   - default: false,
45   - },
46 43 inlineCollapsed: {
47 44 type: Boolean as PropType<boolean>,
48 45 default: false,
... ... @@ -57,7 +54,6 @@ export const basicProps = {
57 54 default: true,
58 55 },
59 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 1 import { MenuModeEnum } from '/@/enums/menuEnum';
2 2 import type { Menu as MenuType } from '/@/router/types';
3 3 import type { MenuState } from './types';
4   -import type { Ref } from 'vue';
  4 +
  5 +import { computed, Ref, toRaw } from 'vue';
5 6  
6 7 import { unref } from 'vue';
7   -import { getAllParentPath } from '/@/router/helper/menuHelper';
8 8 import { es6Unique } from '/@/utils';
9 9 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  10 +import { getAllParentPath } from '/@/router/helper/menuHelper';
10 11  
11 12 export function useOpenKeys(
12 13 menuState: MenuState,
13 14 menus: Ref<MenuType[]>,
14   - flatMenusRef: Ref<MenuType[]>,
15 15 mode: Ref<MenuModeEnum>,
16 16 accordion: Ref<boolean>
17 17 ) {
18 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 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 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 34 * @description: ้‡็ฝฎๅ€ผ
34 35 */
... ... @@ -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 &#39;/@/hooks/web/useFullContent&#39;;
11 11  
12 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 84 return {
85 85 setHeaderSetting,
86 86  
... ...
src/hooks/setting/useLocaleSetting.ts
... ... @@ -6,26 +6,26 @@ import { appStore } from &#39;/@/store/modules/app&#39;;
6 6 import getProjectSetting from '/@/settings/projectSetting';
7 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 29 return {
30 30 getLocale,
31 31 getLang,
... ...
src/hooks/setting/useMenuSetting.ts
... ... @@ -7,89 +7,89 @@ import { appStore } from &#39;/@/store/modules/app&#39;;
7 7 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
8 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 93 return {
94 94 setMenuSetting,
95 95  
... ...
src/hooks/setting/useMultipleTabSetting.ts
... ... @@ -4,17 +4,17 @@ import { computed, unref } from &#39;vue&#39;;
4 4  
5 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 18 return {
19 19 setMultipleTabSetting,
20 20  
... ...
src/hooks/setting/useRootSetting.ts
... ... @@ -9,47 +9,48 @@ type RootSetting = Omit&lt;
9 9 ProjectConfig,
10 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 54 return {
54 55 setRootSetting,
55 56  
... ...
src/hooks/setting/useTransitionSetting.ts
... ... @@ -4,23 +4,23 @@ import { computed, unref } from &#39;vue&#39;;
4 4  
5 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 24 return {
25 25 setTransitionSetting,
26 26  
... ...
src/hooks/web/useDesign.ts
1 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 4 export function useDesign(scope: string) {
5 5 const values = useAppProviderContext();
6   - // const style = cssModule ? useCssModule() : {};
  6 + // const $style = cssModule ? useCssModule() : {};
7 7  
  8 + // const style: Record<string, string> = {};
8 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 16 return {
15   - prefixCls: computed(() => `${values.prefixCls}-${scope}`),
  17 + // prefixCls: computed(() => `${values.prefixCls}-${scope}`),
  18 + prefixCls: `${values.prefixCls}-${scope}`,
16 19 prefixVar: values.prefixCls,
17 20 // style,
18 21 };
... ...
src/hooks/web/useFullContent.ts
... ... @@ -2,12 +2,12 @@ import { computed, unref } from &#39;vue&#39;;
2 2  
3 3 import { appStore } from '/@/store/modules/app';
4 4  
5   -import { useRouter } from 'vue-router';
  5 +import router from '/@/router';
6 6 /**
7 7 * @description: Full screen display content
8 8 */
9 9 export const useFullContent = () => {
10   - const { currentRoute } = useRouter();
  10 + const { currentRoute } = router;
11 11  
12 12 // Whether to display the content in full screen without displaying the menu
13 13 const getFullContent = computed(() => {
... ...
src/hooks/web/usePage.ts
1   -import { appStore } from '/@/store/modules/app';
2 1 import type { RouteLocationRaw } from 'vue-router';
3 2  
4 3 import { PageEnum } from '/@/enums/pageEnum';
... ... @@ -11,7 +10,6 @@ export type RouteLocationRawEx = Omit&lt;RouteLocationRaw, &#39;path&#39;&gt; &amp; { path: PageEn
11 10  
12 11 function handleError(e: Error) {
13 12 console.error(e);
14   - appStore.commitPageLoadingState(false);
15 13 }
16 14  
17 15 // page switch
... ...
src/layouts/default/header/LayoutHeader.tsx
... ... @@ -80,13 +80,7 @@ export default defineComponent({
80 80 const { refreshPage } = useTabs();
81 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 85 const { getShowLocale } = useLocaleSetting();
92 86 const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
... ... @@ -184,7 +178,7 @@ export default defineComponent({
184 178 {/* <div class={[`layout-header__menu `]}> */}
185 179 <LayoutMenu
186 180 isHorizontal={true}
187   - class={`justify-${unref(getTopMenuAlign)}`}
  181 + // class={`justify-${unref(getTopMenuAlign)}`}
188 182 theme={unref(getHeaderTheme)}
189 183 splitType={unref(getSplitType)}
190 184 menuMode={unref(getMenuMode)}
... ...
src/layouts/default/header/LayoutMultipleHeader.tsx
... ... @@ -21,7 +21,7 @@ export default defineComponent({
21 21  
22 22 const injectValue = useLayoutContext();
23 23  
24   - const { getCalcContentWidth } = useMenuSetting();
  24 + const { getCalcContentWidth, getSplit } = useMenuSetting();
25 25  
26 26 const {
27 27 getFixed,
... ... @@ -56,7 +56,8 @@ export default defineComponent({
56 56 (): CSSProperties => {
57 57 const style: CSSProperties = {};
58 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 62 if (unref(getShowFullHeaderRef)) {
62 63 style.top = `${unref(fullHeaderHeightRef)}px`;
... ...
src/layouts/default/menu/index.tsx
1 1 import './index.less';
2 2  
3 3 import { PropType, toRef } from 'vue';
4   -import type { Menu } from '/@/router/types';
5 4  
6 5 import { computed, defineComponent, unref } from 'vue';
7   -import { BasicMenu } from '/@/components/Menu/index';
  6 +import { BasicMenu } from '/@/components/Menu';
8 7 import { AppLogo } from '/@/components/Application';
9 8  
10 9 import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
11 10  
12 11 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
13   -import { useRootSetting } from '/@/hooks/setting/useRootSetting';
14 12  
15 13 import { useGo } from '/@/hooks/web/usePage';
16 14 import { useSplitMenu } from './useLayoutMenu';
17 15 import { openWindow } from '/@/utils';
18 16 import { propTypes } from '/@/utils/propTypes';
  17 +import { isUrl } from '/@/utils/is';
  18 +import { useRootSetting } from '/@/hooks/setting/useRootSetting';
19 19  
20 20 export default defineComponent({
21 21 name: 'LayoutMenu',
... ... @@ -38,56 +38,46 @@ export default defineComponent({
38 38 const go = useGo();
39 39  
40 40 const {
41   - setMenuSetting,
42 41 getMenuMode,
43 42 getMenuType,
44 43 getCollapsedShowTitle,
45   - getIsSidebarType,
46 44 getMenuTheme,
47 45 getCollapsed,
48 46 getAccordion,
  47 + getIsSidebarType,
49 48 } = useMenuSetting();
50   -
51 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 53 const getComputedMenuMode = computed(() => props.menuMode || unref(getMenuMode));
58 54  
59 55 const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
60   -
  56 + const showLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
61 57 const appendClass = computed(() => props.splitType === MenuSplitTyeEnum.TOP);
62   -
63 58 /**
64 59 * click menu
65 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 67 * before click menu
73 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 78 function renderHeader() {
90 79 if (!unref(showLogo)) return null;
  80 +
91 81 return (
92 82 <AppLogo
93 83 showTitle={!unref(getCollapsed)}
... ... @@ -100,20 +90,17 @@ export default defineComponent({
100 90 return () => {
101 91 return (
102 92 <BasicMenu
103   - class="layout-menu"
104 93 beforeClickFn={beforeMenuClickFn}
105 94 isHorizontal={props.isHorizontal}
106   - appendClass={unref(appendClass)}
107 95 type={unref(getMenuType)}
108 96 mode={unref(getComputedMenuMode)}
109 97 collapsedShowTitle={unref(getCollapsedShowTitle)}
110 98 theme={unref(getComputedMenuTheme)}
111   - showLogo={unref(showLogo)}
112 99 items={unref(menusRef)}
113   - flatItems={unref(flatMenusRef)}
114 100 accordion={unref(getAccordion)}
115 101 onMenuClick={handleMenuClick}
116   - onClickSearchInput={handleClickSearchInput}
  102 + appendClass={unref(appendClass)}
  103 + showLogo={unref(showLogo)}
117 104 >
118 105 {{
119 106 header: () => renderHeader(),
... ...
src/layouts/default/menu/useLayoutMenu.ts
... ... @@ -8,24 +8,12 @@ import { MenuSplitTyeEnum } from &#39;/@/enums/menuEnum&#39;;
8 8 import { useThrottle } from '/@/hooks/core/useThrottle';
9 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 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 14 export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
25 15 // Menu array
26 16 const menusRef = ref<Menu[]>([]);
27   - // flat menu array
28   - const flatMenusRef = ref<Menu[]>([]);
29 17  
30 18 const { currentRoute } = useRouter();
31 19  
... ... @@ -45,14 +33,6 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
45 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 36 watch(
57 37 [() => unref(currentRoute).path, () => unref(splitType)],
58 38 async ([path]: [string, MenuSplitTyeEnum]) => {
... ... @@ -83,20 +63,6 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
83 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 66 // Handle left menu split
101 67 async function handleSplitLeftMenu(parentPath: string) {
102 68 if (unref(splitLeft)) return;
... ... @@ -105,14 +71,11 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
105 71 const children = await getChildrenMenus(parentPath);
106 72 if (!children) {
107 73 setMenuSetting({ hidden: false });
108   - flatMenusRef.value = [];
109 74 menusRef.value = [];
110 75 return;
111 76 }
112 77  
113   - const flatChildren = await getFlatChildrenMenus(children);
114 78 setMenuSetting({ hidden: true });
115   - flatMenusRef.value = flatChildren;
116 79 menusRef.value = children;
117 80 }
118 81  
... ... @@ -120,7 +83,6 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
120 83 async function genMenus() {
121 84 // normal mode
122 85 if (unref(normalType)) {
123   - flatMenusRef.value = await getFlatMenus();
124 86 menusRef.value = await getMenus();
125 87 return;
126 88 }
... ... @@ -129,11 +91,10 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
129 91 if (unref(spiltTop)) {
130 92 const shallowMenus = await getShallowMenus();
131 93  
132   - flatMenusRef.value = shallowMenus;
133 94 menusRef.value = shallowMenus;
134 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 12  
13 13 &.ant-layout-sider-dark {
14 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 27 &:not(.ant-layout-sider-dark) {
18 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 36 .ant-layout-sider-zero-width-trigger {
... ... @@ -43,9 +58,9 @@
43 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 100 flex: `0 0 ${width}`,
101 101 maxWidth: width,
102 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 126 )}
127 127 <Layout.Sider
128 128 ref={sideRef}
129   - breakpoint="md"
  129 + breakpoint="lg"
130 130 collapsible
131 131 class={unref(getSiderClass)}
132 132 style={unref(getSiderStyle)}
... ...
src/utils/is.ts
... ... @@ -79,3 +79,8 @@ export const isMobile = (): boolean =&gt; {
79 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 +};
... ...