Commit bb67692cfdd5089f0f1d60d4a36b52592db22dde

Authored by Vben
1 parent 0b66360c

fix(menu): ensure the menu is activated correctly,fix #432

package.json
... ... @@ -34,7 +34,7 @@
34 34 "@iconify/iconify": "^2.0.0-rc.6",
35 35 "@vueuse/core": "^4.6.2",
36 36 "@zxcvbn-ts/core": "^0.3.0",
37   - "ant-design-vue": "2.1.0",
  37 + "ant-design-vue": "2.1.1",
38 38 "apexcharts": "^3.26.0",
39 39 "axios": "^0.21.1",
40 40 "crypto-js": "^4.0.0",
... ...
src/components/SimpleMenu/src/SimpleMenu.vue
... ... @@ -18,7 +18,6 @@
18 18 </Menu>
19 19 </template>
20 20 <script lang="ts">
21   - import type { PropType } from 'vue';
22 21 import type { MenuState } from './types';
23 22 import type { Menu as MenuType } from '/@/router/types';
24 23  
... ... @@ -69,6 +68,7 @@
69 68 const { currentRoute } = useRouter();
70 69 const { prefixCls } = useDesign('simple-menu');
71 70 const { items, accordion, mixSider, collapse } = toRefs(props);
  71 +
72 72 const { setOpenKeys, getOpenKeys } = useOpenKeys(
73 73 menuState,
74 74 items,
... ... @@ -91,6 +91,14 @@
91 91 { immediate: true }
92 92 );
93 93  
  94 + watch(
  95 + () => props.items,
  96 + () => {
  97 + setOpenKeys(currentRoute.value.path);
  98 + },
  99 + { flush: 'post' }
  100 + );
  101 +
94 102 listenerRouteChange((route) => {
95 103 if (route.name === REDIRECT_NAME) return;
96 104  
... ... @@ -112,7 +120,6 @@
112 120 menuState.activeName = path;
113 121  
114 122 setOpenKeys(path);
115   - // if (unref(currentActiveMenu)) return;
116 123 }
117 124  
118 125 async function handleSelect(key: string) {
... ...
src/components/SimpleMenu/src/SimpleMenuTag.vue
... ... @@ -3,7 +3,6 @@
3 3 </template>
4 4 <script lang="ts">
5 5 import type { Menu } from '/@/router/types';
6   - import type { PropType } from 'vue';
7 6  
8 7 import { defineComponent, computed } from 'vue';
9 8  
... ...
src/components/SimpleMenu/src/components/Menu.vue
... ... @@ -18,6 +18,7 @@
18 18 getCurrentInstance,
19 19 provide,
20 20 } from 'vue';
  21 +
21 22 import { useDesign } from '/@/hooks/web/useDesign';
22 23 import { propTypes } from '/@/utils/propTypes';
23 24 import { createSimpleRootMenuContext } from './useSimpleMenuContext';
... ...
src/components/SimpleMenu/src/components/MenuCollapseTransition.vue
... ... @@ -12,7 +12,7 @@
12 12 setup() {
13 13 return {
14 14 on: {
15   - beforeEnter(el: any) {
  15 + beforeEnter(el) {
16 16 addClass(el, 'collapse-transition');
17 17 if (!el.dataset) el.dataset = {};
18 18  
... ... @@ -24,7 +24,7 @@
24 24 el.style.paddingBottom = 0;
25 25 },
26 26  
27   - enter(el: any) {
  27 + enter(el) {
28 28 el.dataset.oldOverflow = el.style.overflow;
29 29 if (el.scrollHeight !== 0) {
30 30 el.style.height = el.scrollHeight + 'px';
... ... @@ -39,13 +39,13 @@
39 39 el.style.overflow = 'hidden';
40 40 },
41 41  
42   - afterEnter(el: any) {
  42 + afterEnter(el) {
43 43 removeClass(el, 'collapse-transition');
44 44 el.style.height = '';
45 45 el.style.overflow = el.dataset.oldOverflow;
46 46 },
47 47  
48   - beforeLeave(el: any) {
  48 + beforeLeave(el) {
49 49 if (!el.dataset) el.dataset = {};
50 50 el.dataset.oldPaddingTop = el.style.paddingTop;
51 51 el.dataset.oldPaddingBottom = el.style.paddingBottom;
... ... @@ -55,7 +55,7 @@
55 55 el.style.overflow = 'hidden';
56 56 },
57 57  
58   - leave(el: any) {
  58 + leave(el) {
59 59 if (el.scrollHeight !== 0) {
60 60 addClass(el, 'collapse-transition');
61 61 el.style.height = 0;
... ... @@ -64,7 +64,7 @@
64 64 }
65 65 },
66 66  
67   - afterLeave(el: any) {
  67 + afterLeave(el) {
68 68 removeClass(el, 'collapse-transition');
69 69 el.style.height = '';
70 70 el.style.overflow = el.dataset.oldOverflow;
... ...
src/components/SimpleMenu/src/components/SubMenuItem.vue
... ... @@ -78,7 +78,7 @@
78 78 import { isBoolean, isObject } from '/@/utils/is';
79 79 import Mitt from '/@/utils/mitt';
80 80  
81   - const DELAY = 200;
  81 + const DELAY = 250;
82 82 export default defineComponent({
83 83 name: 'SubMenu',
84 84 components: {
... ...
src/components/SimpleMenu/src/components/useMenu.ts
... ... @@ -51,7 +51,7 @@ export function useMenuItem(instance: ComponentInternalInstance | null) {
51 51 uidList: [],
52 52 list: [],
53 53 };
54   - const ret = [];
  54 + const ret: any[] = [];
55 55 while (parent && parent.type.name !== 'Menu') {
56 56 if (parent.type.name === 'SubMenu') {
57 57 ret.push(parent);
... ...
src/components/SimpleMenu/src/useOpenKeys.ts
... ... @@ -8,6 +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 12  
12 13 export function useOpenKeys(
13 14 menuState: MenuState,
... ... @@ -15,22 +16,20 @@ export function useOpenKeys(
15 16 accordion: Ref<boolean>,
16 17 mixSider: Ref<boolean>,
17 18 collapse: Ref<boolean>
18   - // mode: Ref<MenuModeEnum>,
19 19 ) {
  20 + const [debounceSetOpenKeys] = useDebounce(setOpenKeys, 50);
20 21 async function setOpenKeys(path: string) {
21   - // if (mode.value === MenuModeEnum.HORIZONTAL) {
22   - // return;
23   - // }
24 22 const native = !mixSider.value;
  23 + const menuList = toRaw(menus.value);
25 24 useTimeoutFn(
26 25 () => {
27   - const menuList = toRaw(menus.value);
28 26 if (menuList?.length === 0) {
29 27 menuState.activeSubMenuNames = [];
30 28 menuState.openNames = [];
31 29 return;
32 30 }
33 31 const keys = getAllParentPath(menuList, path);
  32 +
34 33 if (!unref(accordion)) {
35 34 menuState.openNames = uniq([...menuState.openNames, ...keys]);
36 35 } else {
... ... @@ -38,7 +37,7 @@ export function useOpenKeys(
38 37 }
39 38 menuState.activeSubMenuNames = menuState.openNames;
40 39 },
41   - 16,
  40 + 30,
42 41 native
43 42 );
44 43 }
... ... @@ -47,5 +46,5 @@ export function useOpenKeys(
47 46 return unref(collapse) ? [] : menuState.openNames;
48 47 });
49 48  
50   - return { setOpenKeys, getOpenKeys };
  49 + return { setOpenKeys: debounceSetOpenKeys, getOpenKeys };
51 50 }
... ...
src/layouts/default/menu/index.vue
... ... @@ -92,6 +92,20 @@
92 92 },
93 93 ];
94 94 });
  95 +
  96 + const getCommonProps = computed(() => {
  97 + const menus = unref(menusRef);
  98 + return {
  99 + menus,
  100 + beforeClickFn: beforeMenuClickFn,
  101 + items: menus,
  102 + theme: unref(getComputedMenuTheme),
  103 + accordion: unref(getAccordion),
  104 + collapse: unref(getCollapsed),
  105 + collapsedShowTitle: unref(getCollapsedShowTitle),
  106 + onMenuClick: handleMenuClick,
  107 + };
  108 + });
95 109 /**
96 110 * click menu
97 111 * @param menu
... ... @@ -126,31 +140,19 @@
126 140 }
127 141  
128 142 function renderMenu() {
129   - const menus = unref(menusRef);
  143 + const { menus, ...menuProps } = unref(getCommonProps);
130 144 // console.log(menus);
131 145 if (!menus || !menus.length) return null;
132 146 return !props.isHorizontal ? (
133   - <SimpleMenu
134   - beforeClickFn={beforeMenuClickFn}
135   - items={menus}
136   - theme={unref(getComputedMenuTheme)}
137   - accordion={unref(getAccordion)}
138   - collapse={unref(getCollapsed)}
139   - collapsedShowTitle={unref(getCollapsedShowTitle)}
140   - onMenuClick={handleMenuClick}
141   - />
  147 + <SimpleMenu {...menuProps} items={menus} />
142 148 ) : (
143 149 <BasicMenu
144   - beforeClickFn={beforeMenuClickFn}
  150 + {...menuProps}
145 151 isHorizontal={props.isHorizontal}
146 152 type={unref(getMenuType)}
147   - collapsedShowTitle={unref(getCollapsedShowTitle)}
148 153 showLogo={unref(getIsShowLogo)}
149 154 mode={unref(getComputedMenuMode)}
150   - theme={unref(getComputedMenuTheme)}
151 155 items={menus}
152   - accordion={unref(getAccordion)}
153   - onMenuClick={handleMenuClick}
154 156 />
155 157 );
156 158 }
... ...
src/layouts/default/menu/useLayoutMenu.ts
... ... @@ -65,10 +65,13 @@ export function useSplitMenu(splitType: Ref&lt;MenuSplitTyeEnum&gt;) {
65 65 );
66 66  
67 67 // split Menu changes
68   - watch([() => getSplit.value], () => {
69   - if (unref(splitNotLeft)) return;
70   - genMenus();
71   - });
  68 + watch(
  69 + () => getSplit.value,
  70 + () => {
  71 + if (unref(splitNotLeft)) return;
  72 + genMenus();
  73 + }
  74 + );
72 75  
73 76 // Handle left menu split
74 77 async function handleSplitLeftMenu(parentPath: string) {
... ...
types/global.d.ts
... ... @@ -3,13 +3,18 @@ import type {
3 3 VNode,
4 4 ComponentPublicInstance,
5 5 FunctionalComponent,
  6 + PropType as VuePropType,
6 7 } from 'vue';
  8 +
7 9 declare global {
8 10 // declare interface Window {
9 11 // Global vue app instance
10 12 // __APP__: App<Element>;
11 13 // }
12 14  
  15 + // vue
  16 + declare type PropType<T> = VuePropType<T>;
  17 +
13 18 export type Writable<T> = {
14 19 -readonly [P in keyof T]: T[P];
15 20 };
... ...
yarn.lock
... ... @@ -2284,10 +2284,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
2284 2284 dependencies:
2285 2285 color-convert "^2.0.1"
2286 2286  
2287   -ant-design-vue@2.1.0:
2288   - version "2.1.0"
2289   - resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.0.tgz#2489240f638f39874281e237544b857ebce52d18"
2290   - integrity sha512-wzgwHRuwZrSvixccNlvas2gTWBkmfMrifbSsP+ga8VV6F0C6DdlimeFo+P99AxnVgpNVk8OUq9RVDQjb1UGk6g==
  2287 +ant-design-vue@2.1.1:
  2288 + version "2.1.1"
  2289 + resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.1.tgz#5c2f3d86177e197f6dbb167f691a9d10104e61c3"
  2290 + integrity sha512-ohTEIBFRkODRTFXRHeizL/uKNOZY5+4r2y/GXiKEdvrxiTRgHgDNMWKsncG/+G6MXxOIe2Reg+r8jHS8nGDqtQ==
2291 2291 dependencies:
2292 2292 "@ant-design-vue/use" "^0.0.1-0"
2293 2293 "@ant-design/icons-vue" "^6.0.0"
... ...