admin-vben5/packages/effects/layouts/src/basic/menu/use-mixed-menu.ts

128 lines
2.9 KiB
TypeScript
Raw Normal View History

2024-05-19 21:20:42 +08:00
import type { MenuRecordRaw } from '@vben-core/typings';
import { computed, onBeforeMount, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
2024-05-19 21:20:42 +08:00
2024-06-09 15:39:11 +08:00
import { findRootMenuByPath } from '@vben-core/helpers';
2024-06-08 19:49:06 +08:00
import { preferences, usePreferences } from '@vben-core/preferences';
import { useCoreAccessStore } from '@vben-core/stores';
2024-06-08 19:49:06 +08:00
import { useNavigation } from './use-navigation';
2024-05-19 21:20:42 +08:00
function useMixedMenu() {
const { navigation } = useNavigation();
const accessStore = useCoreAccessStore();
2024-05-19 21:20:42 +08:00
const route = useRoute();
const splitSideMenus = ref<MenuRecordRaw[]>([]);
const rootMenuPath = ref<string>('');
2024-06-01 23:15:29 +08:00
const { isMixedNav } = usePreferences();
2024-05-19 21:20:42 +08:00
2024-05-22 22:38:01 +08:00
const needSplit = computed(
2024-06-01 23:15:29 +08:00
() => preferences.navigation.split && isMixedNav.value,
2024-05-22 22:38:01 +08:00
);
const sidebarVisible = computed(() => {
2024-06-01 23:15:29 +08:00
const enableSidebar = preferences.sidebar.enable;
2024-05-22 22:38:01 +08:00
if (needSplit.value) {
2024-06-01 23:15:29 +08:00
return enableSidebar && splitSideMenus.value.length > 0;
2024-05-19 21:20:42 +08:00
}
2024-06-01 23:15:29 +08:00
return enableSidebar;
2024-05-19 21:20:42 +08:00
});
2024-07-10 00:50:41 +08:00
const menus = computed(() => accessStore.accessMenus);
2024-05-19 21:20:42 +08:00
/**
*
*/
const headerMenus = computed(() => {
2024-05-22 22:38:01 +08:00
if (!needSplit.value) {
2024-05-19 21:20:42 +08:00
return menus.value;
}
return menus.value.map((item) => {
return {
...item,
children: [],
};
});
});
/**
*
*/
const sidebarMenus = computed(() => {
2024-05-22 22:38:01 +08:00
return needSplit.value ? splitSideMenus.value : menus.value;
2024-05-19 21:20:42 +08:00
});
/**
*
*/
const sidebarActive = computed(() => {
2024-05-19 21:20:42 +08:00
return route.path;
});
/**
*
*/
const headerActive = computed(() => {
2024-05-22 22:38:01 +08:00
if (!needSplit.value) {
2024-05-19 21:20:42 +08:00
return route.path;
}
return rootMenuPath.value;
});
/**
*
* @param key
* @param mode
*/
const handleMenuSelect = (key: string, mode?: string) => {
2024-05-22 22:38:01 +08:00
if (!needSplit.value || mode === 'vertical') {
navigation(key);
2024-05-19 21:20:42 +08:00
return;
}
const rootMenu = menus.value.find((item) => item.path === key);
rootMenuPath.value = rootMenu?.path ?? '';
splitSideMenus.value = rootMenu?.children ?? [];
if (splitSideMenus.value.length === 0) {
navigation(key);
2024-05-19 21:20:42 +08:00
}
};
/**
*
* @param path
*/
function calcSideMenus(path: string = route.path) {
let { rootMenu } = findRootMenuByPath(menus.value, path);
if (!rootMenu) {
rootMenu = menus.value.find((item) => item.path === path);
}
rootMenuPath.value = rootMenu?.path ?? '';
splitSideMenus.value = rootMenu?.children ?? [];
}
watch(
() => route.path,
(path: string) => {
calcSideMenus(path);
},
);
2024-05-19 21:20:42 +08:00
// 初始化计算侧边菜单
onBeforeMount(() => {
calcSideMenus();
});
return {
handleMenuSelect,
headerActive,
headerMenus,
sidebarActive,
sidebarMenus,
sidebarVisible,
2024-05-19 21:20:42 +08:00
};
}
export { useMixedMenu };