Parcourir la source

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

Vben il y a 3 ans
Parent
commit
ee1c349858

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -3,6 +3,7 @@
 ### 🐛 Bug Fixes
 
 - 登录页样式修复
+- 修复菜单已知问题
 
 ## 2.2.0 (2021-04-06)
 

+ 16 - 17
src/components/Application/src/AppDarkModeToggle.vue

@@ -3,7 +3,6 @@
     v-if="getShowDarkModeToggle"
     :class="[
       prefixCls,
-      `${prefixCls}--${size}`,
       {
         [`${prefixCls}--dark`]: isDark,
       },
@@ -30,13 +29,13 @@
   export default defineComponent({
     name: 'DarkModeToggle',
     components: { SvgIcon },
-    props: {
-      size: {
-        type: String,
-        default: 'default',
-        validate: (val) => ['default', 'large'].includes(val),
-      },
-    },
+    // props: {
+    //   size: {
+    //     type: String,
+    //     default: 'default',
+    //     validate: (val) => ['default', 'large'].includes(val),
+    //   },
+    // },
     setup() {
       const { prefixCls } = useDesign('dark-mode-toggle');
       const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
@@ -97,15 +96,15 @@
       }
     }
 
-    &--large {
-      width: 72px;
-      height: 34px;
-      padding: 0 10px;
+    // &--large {
+    //   width: 70px;
+    //   height: 34px;
+    //   padding: 0 10px;
 
-      .@{prefix-cls}-inner {
-        width: 26px;
-        height: 26px;
-      }
-    }
+    //   .@{prefix-cls}-inner {
+    //     width: 26px;
+    //     height: 26px;
+    //   }
+    // }
   }
 </style>

+ 1 - 5
src/components/Icon/src/index.vue

@@ -24,8 +24,6 @@
   import Iconify from '@purge-icons/generated';
   import { isString } from '/@/utils/is';
   import { propTypes } from '/@/utils/propTypes';
-  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
-  import { ThemeEnum } from '/@/enums/appEnum';
 
   const SVG_END_WITH_FLAG = '|svg';
   export default defineComponent({
@@ -46,8 +44,6 @@
     setup(props) {
       const elRef = ref<ElRef>(null);
 
-      const { getDarkMode } = useRootSetting();
-
       const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG));
       const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, ''));
       const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`);
@@ -85,7 +81,7 @@
 
           return {
             fontSize: `${fs}px`,
-            color: color || (unref(getDarkMode) === ThemeEnum.DARK ? '#fff' : '#303133'),
+            color: color,
             display: 'inline-flex',
           };
         }

+ 12 - 1
src/components/SimpleMenu/src/SimpleMenu.vue

@@ -1,11 +1,12 @@
 <template>
   <Menu
     v-bind="getBindValues"
-    @select="handleSelect"
     :activeName="activeName"
     :openNames="getOpenKeys"
     :class="prefixCls"
     :activeSubMenuNames="activeSubMenuNames"
+    @select="handleSelect"
+    @open-change="handleOpenChange"
   >
     <template v-for="item in items" :key="item.path">
       <SimpleSubMenu
@@ -53,6 +54,7 @@
       beforeClickFn: {
         type: Function as PropType<(key: string) => Promise<boolean>>,
       },
+      isSplitMenu: propTypes.bool,
     },
     emits: ['menuClick'],
     setup(props, { attrs, emit }) {
@@ -94,6 +96,9 @@
       watch(
         () => props.items,
         () => {
+          if (!props.isSplitMenu) {
+            return;
+          }
           setOpenKeys(currentRoute.value.path);
         },
         { flush: 'post' }
@@ -135,11 +140,17 @@
         menuState.activeName = key;
       }
 
+      function handleOpenChange(v) {
+        console.log('======================');
+        console.log(v);
+        console.log('======================');
+      }
       return {
         prefixCls,
         getBindValues,
         handleSelect,
         getOpenKeys,
+        handleOpenChange,
         ...toRefs(menuState),
       };
     },

+ 9 - 0
src/components/SimpleMenu/src/components/Menu.vue

@@ -138,6 +138,15 @@
           });
           emit('select', name);
         });
+
+        rootMenuEmitter.on('open-name-change', ({ name, opened }) => {
+          if (opened && !openedNames.value.includes(name)) {
+            openedNames.value.push(name);
+          } else if (!opened) {
+            const index = openedNames.value.findIndex((item) => item === name);
+            index !== -1 && openedNames.value.splice(index, 1);
+          }
+        });
       });
 
       return { getClass, openedNames };

+ 7 - 2
src/components/SimpleMenu/src/components/MenuItem.vue

@@ -66,11 +66,16 @@
 
       function handleClickItem() {
         const { disabled } = props;
-        if (disabled) return;
+        if (disabled) {
+          return;
+        }
 
         rootMenuEmitter.emit('on-menu-item-select', props.name);
-        if (unref(getCollapse)) return;
+        if (unref(getCollapse)) {
+          return;
+        }
         const { uidList } = getParentList();
+
         rootMenuEmitter.emit('on-update-opened', {
           opend: false,
           parent: instance?.parent,

+ 10 - 3
src/components/SimpleMenu/src/components/SubMenuItem.vue

@@ -43,8 +43,9 @@
           :class="`${prefixCls}-submenu-title-icon`"
         />
       </div>
-      <template #content>
-        <div v-bind="getEvents(true)" v-show="opened">
+      <!-- eslint-disable-next-line -->
+      <template #content v-show="opened">
+        <div v-bind="getEvents(true)">
           <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`]">
             <slot></slot>
           </ul>
@@ -78,7 +79,7 @@
   import { isBoolean, isObject } from '/@/utils/is';
   import Mitt from '/@/utils/mitt';
 
-  const DELAY = 250;
+  const DELAY = 200;
   export default defineComponent({
     name: 'SubMenu',
     components: {
@@ -189,6 +190,7 @@
         const { disabled } = props;
         if (disabled || unref(getCollapse)) return;
         const opened = state.opened;
+
         if (unref(getAccordion)) {
           const { uidList } = getParentList();
           rootMenuEmitter.emit('on-update-opened', {
@@ -196,6 +198,11 @@
             parent: instance?.parent,
             uidList: uidList,
           });
+        } else {
+          rootMenuEmitter.emit('open-name-change', {
+            name: props.name,
+            opened: !opened,
+          });
         }
         state.opened = !opened;
       }

+ 1 - 1
src/components/SimpleMenu/src/useOpenKeys.ts

@@ -8,7 +8,7 @@ import { uniq } from 'lodash-es';
 import { getAllParentPath } from '/@/router/helper/menuHelper';
 
 import { useTimeoutFn } from '/@/hooks/core/useTimeout';
-import { useDebounce } from '../../../hooks/core/useDebounce';
+import { useDebounce } from '/@/hooks/core/useDebounce';
 
 export function useOpenKeys(
   menuState: MenuState,

+ 2 - 1
src/layouts/default/menu/index.vue

@@ -49,6 +49,7 @@
         getAccordion,
         getIsHorizontal,
         getIsSidebarType,
+        getSplit,
       } = useMenuSetting();
       const { getShowLogo } = useRootSetting();
 
@@ -144,7 +145,7 @@
         // console.log(menus);
         if (!menus || !menus.length) return null;
         return !props.isHorizontal ? (
-          <SimpleMenu {...menuProps} items={menus} />
+          <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
         ) : (
           <BasicMenu
             {...menuProps}

+ 1 - 1
src/layouts/default/setting/SettingDrawer.tsx

@@ -408,7 +408,7 @@ export default defineComponent({
         wrapClassName="setting-drawer"
       >
         {unref(getShowDarkModeToggle) && <Divider>{() => t('layout.setting.darkMode')}</Divider>}
-        {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" size="large" />}
+        {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" />}
         <Divider>{() => t('layout.setting.navMode')}</Divider>
         {renderSidebar()}
         <Divider>{() => t('layout.setting.sysTheme')}</Divider>

+ 1 - 1
src/layouts/default/tabs/index.less

@@ -82,7 +82,7 @@ html[data-theme='dark'] {
       .ant-tabs-tab-active {
         position: relative;
         padding-left: 18px;
-        color: @white;
+        color: @white !important;
         background: @primary-color;
         border: 0;
         transition: none;

+ 1 - 1
src/router/routes/modules/demo/charts.ts

@@ -7,7 +7,7 @@ const charts: AppRouteModule = {
   path: '/charts',
   name: 'Charts',
   component: LAYOUT,
-  redirect: '/charts/apexChart',
+  redirect: '/charts/echarts/map',
   meta: {
     icon: 'ion:bar-chart-outline',
     title: t('routes.demo.charts.charts'),

+ 4 - 0
src/views/sys/login/Login.vue

@@ -112,6 +112,10 @@
       &-form {
         background: transparent !important;
       }
+
+      .app-iconify {
+        color: #fff;
+      }
     }
   }