Files
xj-admin/src/layouts/default/menu/useLayoutMenu.ts
T
2025-06-27 17:42:38 +08:00

131 lines
4.2 KiB
TypeScript

import type { Menu } from '/@/router/types';
import type { Ref } from 'vue';
import { computed, ref, unref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { useThrottleFn } from '@vueuse/core';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
import { usePermissionStore, usePermissionStoreWithOut } from '/@/store/modules/permission';
import { useAppInject } from '/@/hooks/web/useAppInject';
import { listenerMixTopClick } from '/@/logics/mitt/mixTopClick';
export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
// Menu array
const menusRef = ref<Menu[]>([]);
const { currentRoute } = useRouter();
const { getIsMobile } = useAppInject();
const permissionStore = usePermissionStore();
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting();
const throttleHandleSplitLeftMenu = useThrottleFn(handleSplitLeftMenu, 50);
const splitNotLeft = computed(() => unref(splitType) !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontal));
const getSplitLeft = computed(() => !unref(getSplit) || unref(splitType) !== MenuSplitTyeEnum.LEFT);
const getSpiltTop = computed(() => unref(splitType) === MenuSplitTyeEnum.TOP);
const normalType = computed(() => {
return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit);
});
watch(
[() => unref(currentRoute).path, () => unref(splitType)],
async ([path]: [string, MenuSplitTyeEnum]) => {
if (unref(splitNotLeft) || unref(getIsMobile)) return;
const { meta } = unref(currentRoute);
const currentActiveMenu = meta.currentActiveMenu as string;
let parentPath = await getCurrentParentPath(path);
if (!parentPath) {
parentPath = await getCurrentParentPath(currentActiveMenu);
}
parentPath && throttleHandleSplitLeftMenu(parentPath);
},
{
immediate: true,
}
);
// Menu changes
watch(
[() => permissionStore.getLastBuildMenuTime, () => permissionStore.getBackMenuList],
() => {
genMenus();
},
{
immediate: true,
}
);
// split Menu changes
watch(
() => getSplit.value,
() => {
if (unref(splitNotLeft)) return;
genMenus();
}
);
// Handle left menu split
async function handleSplitLeftMenu(parentPath: string) {
if (unref(getSplitLeft) || unref(getIsMobile)) return;
// spilt mode left
const children = await getChildrenMenus(parentPath);
if (!children || !children.length) {
setMenuSetting({ hidden: true });
menusRef.value = [];
return;
}
setMenuSetting({ hidden: false });
menusRef.value = children;
}
listenerMixTopClick((menu) => {
if (!unref(getSplitLeft)) {
menusRef.value = menu?.children || [];
}
});
// get menus
async function genMenus() {
// normal mode
if (unref(normalType) || unref(getIsMobile)) {
menusRef.value = await getMenus();
return;
}
// split-top
if (unref(getSpiltTop)) {
const shallowMenus = await getShallowMenus();
menusRef.value = shallowMenus;
return;
}
}
return { menusRef };
}
export function findRouteMenu(path: string, onlyRoot = false): Menu | undefined {
const permissionStore = usePermissionStoreWithOut();
function findChildren(menus: Menu[]): Menu | undefined {
for (const menu of menus) {
if (menu.path === path) {
return menu;
}
if (!onlyRoot && menu.children && menu.children.length) {
const result = findChildren(menu.children);
if (result !== undefined) {
return result;
}
}
}
return undefined;
}
return findChildren(permissionStore.getBackMenuList);
}