2024-05-19 21:20:42 +08:00
|
|
|
import type { MenuRecordRaw } from '@vben-core/typings';
|
|
|
|
|
2024-07-18 21:59:18 +08:00
|
|
|
import { computed, onBeforeMount, ref, watch } from 'vue';
|
2024-05-21 21:45:48 +08:00
|
|
|
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';
|
2024-07-05 23:15:46 +08:00
|
|
|
import { useCoreAccessStore } from '@vben-core/stores';
|
2024-06-08 19:49:06 +08:00
|
|
|
|
2024-05-21 21:45:48 +08:00
|
|
|
import { useNavigation } from './use-navigation';
|
2024-05-19 21:20:42 +08:00
|
|
|
|
|
|
|
function useMixedMenu() {
|
2024-05-21 21:45:48 +08:00
|
|
|
const { navigation } = useNavigation();
|
2024-07-18 21:59:18 +08:00
|
|
|
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
|
|
|
);
|
|
|
|
|
2024-07-18 21:59:18 +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: [],
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 侧边菜单
|
|
|
|
*/
|
2024-07-18 21:59:18 +08:00
|
|
|
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
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 侧边菜单激活路径
|
|
|
|
*/
|
2024-07-18 21:59:18 +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') {
|
2024-05-21 21:45:48 +08:00
|
|
|
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) {
|
2024-05-21 21:45:48 +08:00
|
|
|
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 ?? [];
|
|
|
|
}
|
|
|
|
|
2024-07-18 21:59:18 +08:00
|
|
|
watch(
|
|
|
|
() => route.path,
|
|
|
|
(path: string) => {
|
|
|
|
calcSideMenus(path);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-05-19 21:20:42 +08:00
|
|
|
// 初始化计算侧边菜单
|
|
|
|
onBeforeMount(() => {
|
|
|
|
calcSideMenus();
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
handleMenuSelect,
|
|
|
|
headerActive,
|
|
|
|
headerMenus,
|
2024-07-18 21:59:18 +08:00
|
|
|
sidebarActive,
|
|
|
|
sidebarMenus,
|
|
|
|
sidebarVisible,
|
2024-05-19 21:20:42 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export { useMixedMenu };
|