提交 bb67692c 作者: Vben

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

上级 0b66360c
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"@iconify/iconify": "^2.0.0-rc.6", "@iconify/iconify": "^2.0.0-rc.6",
"@vueuse/core": "^4.6.2", "@vueuse/core": "^4.6.2",
"@zxcvbn-ts/core": "^0.3.0", "@zxcvbn-ts/core": "^0.3.0",
"ant-design-vue": "2.1.0", "ant-design-vue": "2.1.1",
"apexcharts": "^3.26.0", "apexcharts": "^3.26.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
</Menu> </Menu>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue';
import type { MenuState } from './types'; import type { MenuState } from './types';
import type { Menu as MenuType } from '/@/router/types'; import type { Menu as MenuType } from '/@/router/types';
...@@ -69,6 +68,7 @@ ...@@ -69,6 +68,7 @@
const { currentRoute } = useRouter(); const { currentRoute } = useRouter();
const { prefixCls } = useDesign('simple-menu'); const { prefixCls } = useDesign('simple-menu');
const { items, accordion, mixSider, collapse } = toRefs(props); const { items, accordion, mixSider, collapse } = toRefs(props);
const { setOpenKeys, getOpenKeys } = useOpenKeys( const { setOpenKeys, getOpenKeys } = useOpenKeys(
menuState, menuState,
items, items,
...@@ -91,6 +91,14 @@ ...@@ -91,6 +91,14 @@
{ immediate: true } { immediate: true }
); );
watch(
() => props.items,
() => {
setOpenKeys(currentRoute.value.path);
},
{ flush: 'post' }
);
listenerRouteChange((route) => { listenerRouteChange((route) => {
if (route.name === REDIRECT_NAME) return; if (route.name === REDIRECT_NAME) return;
...@@ -112,7 +120,6 @@ ...@@ -112,7 +120,6 @@
menuState.activeName = path; menuState.activeName = path;
setOpenKeys(path); setOpenKeys(path);
// if (unref(currentActiveMenu)) return;
} }
async function handleSelect(key: string) { async function handleSelect(key: string) {
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import type { Menu } from '/@/router/types'; import type { Menu } from '/@/router/types';
import type { PropType } from 'vue';
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
getCurrentInstance, getCurrentInstance,
provide, provide,
} from 'vue'; } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
import { propTypes } from '/@/utils/propTypes'; import { propTypes } from '/@/utils/propTypes';
import { createSimpleRootMenuContext } from './useSimpleMenuContext'; import { createSimpleRootMenuContext } from './useSimpleMenuContext';
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
setup() { setup() {
return { return {
on: { on: {
beforeEnter(el: any) { beforeEnter(el) {
addClass(el, 'collapse-transition'); addClass(el, 'collapse-transition');
if (!el.dataset) el.dataset = {}; if (!el.dataset) el.dataset = {};
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
el.style.paddingBottom = 0; el.style.paddingBottom = 0;
}, },
enter(el: any) { enter(el) {
el.dataset.oldOverflow = el.style.overflow; el.dataset.oldOverflow = el.style.overflow;
if (el.scrollHeight !== 0) { if (el.scrollHeight !== 0) {
el.style.height = el.scrollHeight + 'px'; el.style.height = el.scrollHeight + 'px';
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
el.style.overflow = 'hidden'; el.style.overflow = 'hidden';
}, },
afterEnter(el: any) { afterEnter(el) {
removeClass(el, 'collapse-transition'); removeClass(el, 'collapse-transition');
el.style.height = ''; el.style.height = '';
el.style.overflow = el.dataset.oldOverflow; el.style.overflow = el.dataset.oldOverflow;
}, },
beforeLeave(el: any) { beforeLeave(el) {
if (!el.dataset) el.dataset = {}; if (!el.dataset) el.dataset = {};
el.dataset.oldPaddingTop = el.style.paddingTop; el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom; el.dataset.oldPaddingBottom = el.style.paddingBottom;
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
el.style.overflow = 'hidden'; el.style.overflow = 'hidden';
}, },
leave(el: any) { leave(el) {
if (el.scrollHeight !== 0) { if (el.scrollHeight !== 0) {
addClass(el, 'collapse-transition'); addClass(el, 'collapse-transition');
el.style.height = 0; el.style.height = 0;
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
} }
}, },
afterLeave(el: any) { afterLeave(el) {
removeClass(el, 'collapse-transition'); removeClass(el, 'collapse-transition');
el.style.height = ''; el.style.height = '';
el.style.overflow = el.dataset.oldOverflow; el.style.overflow = el.dataset.oldOverflow;
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
import { isBoolean, isObject } from '/@/utils/is'; import { isBoolean, isObject } from '/@/utils/is';
import Mitt from '/@/utils/mitt'; import Mitt from '/@/utils/mitt';
const DELAY = 200; const DELAY = 250;
export default defineComponent({ export default defineComponent({
name: 'SubMenu', name: 'SubMenu',
components: { components: {
......
...@@ -51,7 +51,7 @@ export function useMenuItem(instance: ComponentInternalInstance | null) { ...@@ -51,7 +51,7 @@ export function useMenuItem(instance: ComponentInternalInstance | null) {
uidList: [], uidList: [],
list: [], list: [],
}; };
const ret = []; const ret: any[] = [];
while (parent && parent.type.name !== 'Menu') { while (parent && parent.type.name !== 'Menu') {
if (parent.type.name === 'SubMenu') { if (parent.type.name === 'SubMenu') {
ret.push(parent); ret.push(parent);
......
...@@ -8,6 +8,7 @@ import { uniq } from 'lodash-es'; ...@@ -8,6 +8,7 @@ import { uniq } from 'lodash-es';
import { getAllParentPath } from '/@/router/helper/menuHelper'; import { getAllParentPath } from '/@/router/helper/menuHelper';
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { useDebounce } from '../../../hooks/core/useDebounce';
export function useOpenKeys( export function useOpenKeys(
menuState: MenuState, menuState: MenuState,
...@@ -15,22 +16,20 @@ export function useOpenKeys( ...@@ -15,22 +16,20 @@ export function useOpenKeys(
accordion: Ref<boolean>, accordion: Ref<boolean>,
mixSider: Ref<boolean>, mixSider: Ref<boolean>,
collapse: Ref<boolean> collapse: Ref<boolean>
// mode: Ref<MenuModeEnum>,
) { ) {
const [debounceSetOpenKeys] = useDebounce(setOpenKeys, 50);
async function setOpenKeys(path: string) { async function setOpenKeys(path: string) {
// if (mode.value === MenuModeEnum.HORIZONTAL) {
// return;
// }
const native = !mixSider.value; const native = !mixSider.value;
const menuList = toRaw(menus.value);
useTimeoutFn( useTimeoutFn(
() => { () => {
const menuList = toRaw(menus.value);
if (menuList?.length === 0) { if (menuList?.length === 0) {
menuState.activeSubMenuNames = []; menuState.activeSubMenuNames = [];
menuState.openNames = []; menuState.openNames = [];
return; return;
} }
const keys = getAllParentPath(menuList, path); const keys = getAllParentPath(menuList, path);
if (!unref(accordion)) { if (!unref(accordion)) {
menuState.openNames = uniq([...menuState.openNames, ...keys]); menuState.openNames = uniq([...menuState.openNames, ...keys]);
} else { } else {
...@@ -38,7 +37,7 @@ export function useOpenKeys( ...@@ -38,7 +37,7 @@ export function useOpenKeys(
} }
menuState.activeSubMenuNames = menuState.openNames; menuState.activeSubMenuNames = menuState.openNames;
}, },
16, 30,
native native
); );
} }
...@@ -47,5 +46,5 @@ export function useOpenKeys( ...@@ -47,5 +46,5 @@ export function useOpenKeys(
return unref(collapse) ? [] : menuState.openNames; return unref(collapse) ? [] : menuState.openNames;
}); });
return { setOpenKeys, getOpenKeys }; return { setOpenKeys: debounceSetOpenKeys, getOpenKeys };
} }
...@@ -92,6 +92,20 @@ ...@@ -92,6 +92,20 @@
}, },
]; ];
}); });
const getCommonProps = computed(() => {
const menus = unref(menusRef);
return {
menus,
beforeClickFn: beforeMenuClickFn,
items: menus,
theme: unref(getComputedMenuTheme),
accordion: unref(getAccordion),
collapse: unref(getCollapsed),
collapsedShowTitle: unref(getCollapsedShowTitle),
onMenuClick: handleMenuClick,
};
});
/** /**
* click menu * click menu
* @param menu * @param menu
...@@ -126,31 +140,19 @@ ...@@ -126,31 +140,19 @@
} }
function renderMenu() { function renderMenu() {
const menus = unref(menusRef); const { menus, ...menuProps } = unref(getCommonProps);
// console.log(menus); // console.log(menus);
if (!menus || !menus.length) return null; if (!menus || !menus.length) return null;
return !props.isHorizontal ? ( return !props.isHorizontal ? (
<SimpleMenu <SimpleMenu {...menuProps} items={menus} />
beforeClickFn={beforeMenuClickFn}
items={menus}
theme={unref(getComputedMenuTheme)}
accordion={unref(getAccordion)}
collapse={unref(getCollapsed)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
onMenuClick={handleMenuClick}
/>
) : ( ) : (
<BasicMenu <BasicMenu
beforeClickFn={beforeMenuClickFn} {...menuProps}
isHorizontal={props.isHorizontal} isHorizontal={props.isHorizontal}
type={unref(getMenuType)} type={unref(getMenuType)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
showLogo={unref(getIsShowLogo)} showLogo={unref(getIsShowLogo)}
mode={unref(getComputedMenuMode)} mode={unref(getComputedMenuMode)}
theme={unref(getComputedMenuTheme)}
items={menus} items={menus}
accordion={unref(getAccordion)}
onMenuClick={handleMenuClick}
/> />
); );
} }
......
...@@ -65,10 +65,13 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { ...@@ -65,10 +65,13 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
); );
// split Menu changes // split Menu changes
watch([() => getSplit.value], () => { watch(
() => getSplit.value,
() => {
if (unref(splitNotLeft)) return; if (unref(splitNotLeft)) return;
genMenus(); genMenus();
}); }
);
// Handle left menu split // Handle left menu split
async function handleSplitLeftMenu(parentPath: string) { async function handleSplitLeftMenu(parentPath: string) {
......
...@@ -3,13 +3,18 @@ import type { ...@@ -3,13 +3,18 @@ import type {
VNode, VNode,
ComponentPublicInstance, ComponentPublicInstance,
FunctionalComponent, FunctionalComponent,
PropType as VuePropType,
} from 'vue'; } from 'vue';
declare global { declare global {
// declare interface Window { // declare interface Window {
// Global vue app instance // Global vue app instance
// __APP__: App<Element>; // __APP__: App<Element>;
// } // }
// vue
declare type PropType<T> = VuePropType<T>;
export type Writable<T> = { export type Writable<T> = {
-readonly [P in keyof T]: T[P]; -readonly [P in keyof T]: T[P];
}; };
......
...@@ -2284,10 +2284,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: ...@@ -2284,10 +2284,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies: dependencies:
color-convert "^2.0.1" color-convert "^2.0.1"
ant-design-vue@2.1.0: ant-design-vue@2.1.1:
version "2.1.0" version "2.1.1"
resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.0.tgz#2489240f638f39874281e237544b857ebce52d18" resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.1.tgz#5c2f3d86177e197f6dbb167f691a9d10104e61c3"
integrity sha512-wzgwHRuwZrSvixccNlvas2gTWBkmfMrifbSsP+ga8VV6F0C6DdlimeFo+P99AxnVgpNVk8OUq9RVDQjb1UGk6g== integrity sha512-ohTEIBFRkODRTFXRHeizL/uKNOZY5+4r2y/GXiKEdvrxiTRgHgDNMWKsncG/+G6MXxOIe2Reg+r8jHS8nGDqtQ==
dependencies: dependencies:
"@ant-design-vue/use" "^0.0.1-0" "@ant-design-vue/use" "^0.0.1-0"
"@ant-design/icons-vue" "^6.0.0" "@ant-design/icons-vue" "^6.0.0"
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论