mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 04:39:12 +08:00
fix(menu): ensure the menu is activated correctly,fix #432
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
"@iconify/iconify": "^2.0.0-rc.6",
|
||||
"@vueuse/core": "^4.6.2",
|
||||
"@zxcvbn-ts/core": "^0.3.0",
|
||||
"ant-design-vue": "2.1.0",
|
||||
"ant-design-vue": "2.1.1",
|
||||
"apexcharts": "^3.26.0",
|
||||
"axios": "^0.21.1",
|
||||
"crypto-js": "^4.0.0",
|
||||
|
@@ -18,7 +18,6 @@
|
||||
</Menu>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import type { MenuState } from './types';
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
|
||||
@@ -69,6 +68,7 @@
|
||||
const { currentRoute } = useRouter();
|
||||
const { prefixCls } = useDesign('simple-menu');
|
||||
const { items, accordion, mixSider, collapse } = toRefs(props);
|
||||
|
||||
const { setOpenKeys, getOpenKeys } = useOpenKeys(
|
||||
menuState,
|
||||
items,
|
||||
@@ -91,6 +91,14 @@
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
setOpenKeys(currentRoute.value.path);
|
||||
},
|
||||
{ flush: 'post' }
|
||||
);
|
||||
|
||||
listenerRouteChange((route) => {
|
||||
if (route.name === REDIRECT_NAME) return;
|
||||
|
||||
@@ -112,7 +120,6 @@
|
||||
menuState.activeName = path;
|
||||
|
||||
setOpenKeys(path);
|
||||
// if (unref(currentActiveMenu)) return;
|
||||
}
|
||||
|
||||
async function handleSelect(key: string) {
|
||||
|
@@ -3,7 +3,6 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
import { defineComponent, computed } from 'vue';
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
getCurrentInstance,
|
||||
provide,
|
||||
} from 'vue';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { createSimpleRootMenuContext } from './useSimpleMenuContext';
|
||||
|
@@ -12,7 +12,7 @@
|
||||
setup() {
|
||||
return {
|
||||
on: {
|
||||
beforeEnter(el: any) {
|
||||
beforeEnter(el) {
|
||||
addClass(el, 'collapse-transition');
|
||||
if (!el.dataset) el.dataset = {};
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
el.style.paddingBottom = 0;
|
||||
},
|
||||
|
||||
enter(el: any) {
|
||||
enter(el) {
|
||||
el.dataset.oldOverflow = el.style.overflow;
|
||||
if (el.scrollHeight !== 0) {
|
||||
el.style.height = el.scrollHeight + 'px';
|
||||
@@ -39,13 +39,13 @@
|
||||
el.style.overflow = 'hidden';
|
||||
},
|
||||
|
||||
afterEnter(el: any) {
|
||||
afterEnter(el) {
|
||||
removeClass(el, 'collapse-transition');
|
||||
el.style.height = '';
|
||||
el.style.overflow = el.dataset.oldOverflow;
|
||||
},
|
||||
|
||||
beforeLeave(el: any) {
|
||||
beforeLeave(el) {
|
||||
if (!el.dataset) el.dataset = {};
|
||||
el.dataset.oldPaddingTop = el.style.paddingTop;
|
||||
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
||||
@@ -55,7 +55,7 @@
|
||||
el.style.overflow = 'hidden';
|
||||
},
|
||||
|
||||
leave(el: any) {
|
||||
leave(el) {
|
||||
if (el.scrollHeight !== 0) {
|
||||
addClass(el, 'collapse-transition');
|
||||
el.style.height = 0;
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
afterLeave(el: any) {
|
||||
afterLeave(el) {
|
||||
removeClass(el, 'collapse-transition');
|
||||
el.style.height = '';
|
||||
el.style.overflow = el.dataset.oldOverflow;
|
||||
|
@@ -78,7 +78,7 @@
|
||||
import { isBoolean, isObject } from '/@/utils/is';
|
||||
import Mitt from '/@/utils/mitt';
|
||||
|
||||
const DELAY = 200;
|
||||
const DELAY = 250;
|
||||
export default defineComponent({
|
||||
name: 'SubMenu',
|
||||
components: {
|
||||
|
@@ -51,7 +51,7 @@ export function useMenuItem(instance: ComponentInternalInstance | null) {
|
||||
uidList: [],
|
||||
list: [],
|
||||
};
|
||||
const ret = [];
|
||||
const ret: any[] = [];
|
||||
while (parent && parent.type.name !== 'Menu') {
|
||||
if (parent.type.name === 'SubMenu') {
|
||||
ret.push(parent);
|
||||
|
@@ -8,6 +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';
|
||||
|
||||
export function useOpenKeys(
|
||||
menuState: MenuState,
|
||||
@@ -15,22 +16,20 @@ export function useOpenKeys(
|
||||
accordion: Ref<boolean>,
|
||||
mixSider: Ref<boolean>,
|
||||
collapse: Ref<boolean>
|
||||
// mode: Ref<MenuModeEnum>,
|
||||
) {
|
||||
const [debounceSetOpenKeys] = useDebounce(setOpenKeys, 50);
|
||||
async function setOpenKeys(path: string) {
|
||||
// if (mode.value === MenuModeEnum.HORIZONTAL) {
|
||||
// return;
|
||||
// }
|
||||
const native = !mixSider.value;
|
||||
const menuList = toRaw(menus.value);
|
||||
useTimeoutFn(
|
||||
() => {
|
||||
const menuList = toRaw(menus.value);
|
||||
if (menuList?.length === 0) {
|
||||
menuState.activeSubMenuNames = [];
|
||||
menuState.openNames = [];
|
||||
return;
|
||||
}
|
||||
const keys = getAllParentPath(menuList, path);
|
||||
|
||||
if (!unref(accordion)) {
|
||||
menuState.openNames = uniq([...menuState.openNames, ...keys]);
|
||||
} else {
|
||||
@@ -38,7 +37,7 @@ export function useOpenKeys(
|
||||
}
|
||||
menuState.activeSubMenuNames = menuState.openNames;
|
||||
},
|
||||
16,
|
||||
30,
|
||||
native
|
||||
);
|
||||
}
|
||||
@@ -47,5 +46,5 @@ export function useOpenKeys(
|
||||
return unref(collapse) ? [] : menuState.openNames;
|
||||
});
|
||||
|
||||
return { setOpenKeys, getOpenKeys };
|
||||
return { setOpenKeys: debounceSetOpenKeys, getOpenKeys };
|
||||
}
|
||||
|
@@ -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
|
||||
* @param menu
|
||||
@@ -126,31 +140,19 @@
|
||||
}
|
||||
|
||||
function renderMenu() {
|
||||
const menus = unref(menusRef);
|
||||
const { menus, ...menuProps } = unref(getCommonProps);
|
||||
// console.log(menus);
|
||||
if (!menus || !menus.length) return null;
|
||||
return !props.isHorizontal ? (
|
||||
<SimpleMenu
|
||||
beforeClickFn={beforeMenuClickFn}
|
||||
items={menus}
|
||||
theme={unref(getComputedMenuTheme)}
|
||||
accordion={unref(getAccordion)}
|
||||
collapse={unref(getCollapsed)}
|
||||
collapsedShowTitle={unref(getCollapsedShowTitle)}
|
||||
onMenuClick={handleMenuClick}
|
||||
/>
|
||||
<SimpleMenu {...menuProps} items={menus} />
|
||||
) : (
|
||||
<BasicMenu
|
||||
beforeClickFn={beforeMenuClickFn}
|
||||
{...menuProps}
|
||||
isHorizontal={props.isHorizontal}
|
||||
type={unref(getMenuType)}
|
||||
collapsedShowTitle={unref(getCollapsedShowTitle)}
|
||||
showLogo={unref(getIsShowLogo)}
|
||||
mode={unref(getComputedMenuMode)}
|
||||
theme={unref(getComputedMenuTheme)}
|
||||
items={menus}
|
||||
accordion={unref(getAccordion)}
|
||||
onMenuClick={handleMenuClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@@ -65,10 +65,13 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||
);
|
||||
|
||||
// split Menu changes
|
||||
watch([() => getSplit.value], () => {
|
||||
if (unref(splitNotLeft)) return;
|
||||
genMenus();
|
||||
});
|
||||
watch(
|
||||
() => getSplit.value,
|
||||
() => {
|
||||
if (unref(splitNotLeft)) return;
|
||||
genMenus();
|
||||
}
|
||||
);
|
||||
|
||||
// Handle left menu split
|
||||
async function handleSplitLeftMenu(parentPath: string) {
|
||||
|
5
types/global.d.ts
vendored
5
types/global.d.ts
vendored
@@ -3,13 +3,18 @@ import type {
|
||||
VNode,
|
||||
ComponentPublicInstance,
|
||||
FunctionalComponent,
|
||||
PropType as VuePropType,
|
||||
} from 'vue';
|
||||
|
||||
declare global {
|
||||
// declare interface Window {
|
||||
// Global vue app instance
|
||||
// __APP__: App<Element>;
|
||||
// }
|
||||
|
||||
// vue
|
||||
declare type PropType<T> = VuePropType<T>;
|
||||
|
||||
export type Writable<T> = {
|
||||
-readonly [P in keyof T]: T[P];
|
||||
};
|
||||
|
@@ -2284,10 +2284,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
ant-design-vue@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.0.tgz#2489240f638f39874281e237544b857ebce52d18"
|
||||
integrity sha512-wzgwHRuwZrSvixccNlvas2gTWBkmfMrifbSsP+ga8VV6F0C6DdlimeFo+P99AxnVgpNVk8OUq9RVDQjb1UGk6g==
|
||||
ant-design-vue@2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.1.1.tgz#5c2f3d86177e197f6dbb167f691a9d10104e61c3"
|
||||
integrity sha512-ohTEIBFRkODRTFXRHeizL/uKNOZY5+4r2y/GXiKEdvrxiTRgHgDNMWKsncG/+G6MXxOIe2Reg+r8jHS8nGDqtQ==
|
||||
dependencies:
|
||||
"@ant-design-vue/use" "^0.0.1-0"
|
||||
"@ant-design/icons-vue" "^6.0.0"
|
||||
|
Reference in New Issue
Block a user