Commit ee1c3498587951a6a4cc0b49edb9dacf3f2af5c3

Authored by Vben
1 parent 780a8a67

fix(menu): improve menu logic, fix #461

CHANGELOG.zh_CN.md
... ... @@ -3,6 +3,7 @@
3 3 ### 🐛 Bug Fixes
4 4  
5 5 - 登录页样式修复
  6 +- 修复菜单已知问题
6 7  
7 8 ## 2.2.0 (2021-04-06)
8 9  
... ...
src/components/Application/src/AppDarkModeToggle.vue
... ... @@ -3,7 +3,6 @@
3 3 v-if="getShowDarkModeToggle"
4 4 :class="[
5 5 prefixCls,
6   - `${prefixCls}--${size}`,
7 6 {
8 7 [`${prefixCls}--dark`]: isDark,
9 8 },
... ... @@ -30,13 +29,13 @@
30 29 export default defineComponent({
31 30 name: 'DarkModeToggle',
32 31 components: { SvgIcon },
33   - props: {
34   - size: {
35   - type: String,
36   - default: 'default',
37   - validate: (val) => ['default', 'large'].includes(val),
38   - },
39   - },
  32 + // props: {
  33 + // size: {
  34 + // type: String,
  35 + // default: 'default',
  36 + // validate: (val) => ['default', 'large'].includes(val),
  37 + // },
  38 + // },
40 39 setup() {
41 40 const { prefixCls } = useDesign('dark-mode-toggle');
42 41 const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
... ... @@ -97,15 +96,15 @@
97 96 }
98 97 }
99 98  
100   - &--large {
101   - width: 72px;
102   - height: 34px;
103   - padding: 0 10px;
  99 + // &--large {
  100 + // width: 70px;
  101 + // height: 34px;
  102 + // padding: 0 10px;
104 103  
105   - .@{prefix-cls}-inner {
106   - width: 26px;
107   - height: 26px;
108   - }
109   - }
  104 + // .@{prefix-cls}-inner {
  105 + // width: 26px;
  106 + // height: 26px;
  107 + // }
  108 + // }
110 109 }
111 110 </style>
... ...
src/components/Icon/src/index.vue
... ... @@ -24,8 +24,6 @@
24 24 import Iconify from '@purge-icons/generated';
25 25 import { isString } from '/@/utils/is';
26 26 import { propTypes } from '/@/utils/propTypes';
27   - import { useRootSetting } from '/@/hooks/setting/useRootSetting';
28   - import { ThemeEnum } from '/@/enums/appEnum';
29 27  
30 28 const SVG_END_WITH_FLAG = '|svg';
31 29 export default defineComponent({
... ... @@ -46,8 +44,6 @@
46 44 setup(props) {
47 45 const elRef = ref<ElRef>(null);
48 46  
49   - const { getDarkMode } = useRootSetting();
50   -
51 47 const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG));
52 48 const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, ''));
53 49 const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`);
... ... @@ -85,7 +81,7 @@
85 81  
86 82 return {
87 83 fontSize: `${fs}px`,
88   - color: color || (unref(getDarkMode) === ThemeEnum.DARK ? '#fff' : '#303133'),
  84 + color: color,
89 85 display: 'inline-flex',
90 86 };
91 87 }
... ...
src/components/SimpleMenu/src/SimpleMenu.vue
1 1 <template>
2 2 <Menu
3 3 v-bind="getBindValues"
4   - @select="handleSelect"
5 4 :activeName="activeName"
6 5 :openNames="getOpenKeys"
7 6 :class="prefixCls"
8 7 :activeSubMenuNames="activeSubMenuNames"
  8 + @select="handleSelect"
  9 + @open-change="handleOpenChange"
9 10 >
10 11 <template v-for="item in items" :key="item.path">
11 12 <SimpleSubMenu
... ... @@ -53,6 +54,7 @@
53 54 beforeClickFn: {
54 55 type: Function as PropType<(key: string) => Promise<boolean>>,
55 56 },
  57 + isSplitMenu: propTypes.bool,
56 58 },
57 59 emits: ['menuClick'],
58 60 setup(props, { attrs, emit }) {
... ... @@ -94,6 +96,9 @@
94 96 watch(
95 97 () => props.items,
96 98 () => {
  99 + if (!props.isSplitMenu) {
  100 + return;
  101 + }
97 102 setOpenKeys(currentRoute.value.path);
98 103 },
99 104 { flush: 'post' }
... ... @@ -135,11 +140,17 @@
135 140 menuState.activeName = key;
136 141 }
137 142  
  143 + function handleOpenChange(v) {
  144 + console.log('======================');
  145 + console.log(v);
  146 + console.log('======================');
  147 + }
138 148 return {
139 149 prefixCls,
140 150 getBindValues,
141 151 handleSelect,
142 152 getOpenKeys,
  153 + handleOpenChange,
143 154 ...toRefs(menuState),
144 155 };
145 156 },
... ...
src/components/SimpleMenu/src/components/Menu.vue
... ... @@ -138,6 +138,15 @@
138 138 });
139 139 emit('select', name);
140 140 });
  141 +
  142 + rootMenuEmitter.on('open-name-change', ({ name, opened }) => {
  143 + if (opened && !openedNames.value.includes(name)) {
  144 + openedNames.value.push(name);
  145 + } else if (!opened) {
  146 + const index = openedNames.value.findIndex((item) => item === name);
  147 + index !== -1 && openedNames.value.splice(index, 1);
  148 + }
  149 + });
141 150 });
142 151  
143 152 return { getClass, openedNames };
... ...
src/components/SimpleMenu/src/components/MenuItem.vue
... ... @@ -66,11 +66,16 @@
66 66  
67 67 function handleClickItem() {
68 68 const { disabled } = props;
69   - if (disabled) return;
  69 + if (disabled) {
  70 + return;
  71 + }
70 72  
71 73 rootMenuEmitter.emit('on-menu-item-select', props.name);
72   - if (unref(getCollapse)) return;
  74 + if (unref(getCollapse)) {
  75 + return;
  76 + }
73 77 const { uidList } = getParentList();
  78 +
74 79 rootMenuEmitter.emit('on-update-opened', {
75 80 opend: false,
76 81 parent: instance?.parent,
... ...
src/components/SimpleMenu/src/components/SubMenuItem.vue
... ... @@ -43,8 +43,9 @@
43 43 :class="`${prefixCls}-submenu-title-icon`"
44 44 />
45 45 </div>
46   - <template #content>
47   - <div v-bind="getEvents(true)" v-show="opened">
  46 + <!-- eslint-disable-next-line -->
  47 + <template #content v-show="opened">
  48 + <div v-bind="getEvents(true)">
48 49 <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`]">
49 50 <slot></slot>
50 51 </ul>
... ... @@ -78,7 +79,7 @@
78 79 import { isBoolean, isObject } from '/@/utils/is';
79 80 import Mitt from '/@/utils/mitt';
80 81  
81   - const DELAY = 250;
  82 + const DELAY = 200;
82 83 export default defineComponent({
83 84 name: 'SubMenu',
84 85 components: {
... ... @@ -189,6 +190,7 @@
189 190 const { disabled } = props;
190 191 if (disabled || unref(getCollapse)) return;
191 192 const opened = state.opened;
  193 +
192 194 if (unref(getAccordion)) {
193 195 const { uidList } = getParentList();
194 196 rootMenuEmitter.emit('on-update-opened', {
... ... @@ -196,6 +198,11 @@
196 198 parent: instance?.parent,
197 199 uidList: uidList,
198 200 });
  201 + } else {
  202 + rootMenuEmitter.emit('open-name-change', {
  203 + name: props.name,
  204 + opened: !opened,
  205 + });
199 206 }
200 207 state.opened = !opened;
201 208 }
... ...
src/components/SimpleMenu/src/useOpenKeys.ts
... ... @@ -8,7 +8,7 @@ import { uniq } from &#39;lodash-es&#39;;
8 8 import { getAllParentPath } from '/@/router/helper/menuHelper';
9 9  
10 10 import { useTimeoutFn } from '/@/hooks/core/useTimeout';
11   -import { useDebounce } from '../../../hooks/core/useDebounce';
  11 +import { useDebounce } from '/@/hooks/core/useDebounce';
12 12  
13 13 export function useOpenKeys(
14 14 menuState: MenuState,
... ...
src/layouts/default/menu/index.vue
... ... @@ -49,6 +49,7 @@
49 49 getAccordion,
50 50 getIsHorizontal,
51 51 getIsSidebarType,
  52 + getSplit,
52 53 } = useMenuSetting();
53 54 const { getShowLogo } = useRootSetting();
54 55  
... ... @@ -144,7 +145,7 @@
144 145 // console.log(menus);
145 146 if (!menus || !menus.length) return null;
146 147 return !props.isHorizontal ? (
147   - <SimpleMenu {...menuProps} items={menus} />
  148 + <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
148 149 ) : (
149 150 <BasicMenu
150 151 {...menuProps}
... ...
src/layouts/default/setting/SettingDrawer.tsx
... ... @@ -408,7 +408,7 @@ export default defineComponent({
408 408 wrapClassName="setting-drawer"
409 409 >
410 410 {unref(getShowDarkModeToggle) && <Divider>{() => t('layout.setting.darkMode')}</Divider>}
411   - {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" size="large" />}
  411 + {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" />}
412 412 <Divider>{() => t('layout.setting.navMode')}</Divider>
413 413 {renderSidebar()}
414 414 <Divider>{() => t('layout.setting.sysTheme')}</Divider>
... ...
src/layouts/default/tabs/index.less
... ... @@ -82,7 +82,7 @@ html[data-theme=&#39;dark&#39;] {
82 82 .ant-tabs-tab-active {
83 83 position: relative;
84 84 padding-left: 18px;
85   - color: @white;
  85 + color: @white !important;
86 86 background: @primary-color;
87 87 border: 0;
88 88 transition: none;
... ...
src/router/routes/modules/demo/charts.ts
... ... @@ -7,7 +7,7 @@ const charts: AppRouteModule = {
7 7 path: '/charts',
8 8 name: 'Charts',
9 9 component: LAYOUT,
10   - redirect: '/charts/apexChart',
  10 + redirect: '/charts/echarts/map',
11 11 meta: {
12 12 icon: 'ion:bar-chart-outline',
13 13 title: t('routes.demo.charts.charts'),
... ...
src/views/sys/login/Login.vue
... ... @@ -112,6 +112,10 @@
112 112 &-form {
113 113 background: transparent !important;
114 114 }
  115 +
  116 + .app-iconify {
  117 + color: #fff;
  118 + }
115 119 }
116 120 }
117 121  
... ...