| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- import type { ComputedRef } from 'vue';
- import type { MenuRecordRaw } from '@vben/types';
- import { computed, ref, watch } from 'vue';
- import { useRoute } from 'vue-router';
- import { preferences } from '@vben/preferences';
- import { useAccessStore } from '@vben/stores';
- import { findRootMenuByPath } from '@vben/utils';
- import { useNavigation } from './use-navigation';
- function useExtraMenu(useRootMenus?: ComputedRef<MenuRecordRaw[]>) {
- const accessStore = useAccessStore();
- const { navigation, willOpenedByWindow } = useNavigation();
- const menus = computed(() => useRootMenus?.value ?? accessStore.accessMenus);
- /** 记录当前顶级菜单下哪个子菜单最后激活 */
- const defaultSubMap = new Map<string, string>();
- const extraRootMenus = ref<MenuRecordRaw[]>([]);
- const route = useRoute();
- const extraMenus = ref<MenuRecordRaw[]>([]);
- const sidebarExtraVisible = ref<boolean>(false);
- const extraActiveMenu = ref('');
- const parentLevel = computed(() =>
- preferences.app.layout === 'header-mixed-nav' ? 1 : 0,
- );
- /**
- * 选择混合菜单事件
- * @param menu
- */
- const handleMixedMenuSelect = async (menu: MenuRecordRaw) => {
- const _extraMenus = menu?.children ?? [];
- const hasChildren = _extraMenus.length > 0;
- if (!willOpenedByWindow(menu.path)) {
- extraMenus.value = _extraMenus ?? [];
- extraActiveMenu.value = menu.parents?.[parentLevel.value] ?? menu.path;
- sidebarExtraVisible.value = hasChildren;
- }
- if (!hasChildren) {
- await navigation(menu.path);
- } else if (preferences.sidebar.autoActivateChild) {
- await navigation(
- defaultSubMap.has(menu.path)
- ? (defaultSubMap.get(menu.path) as string)
- : menu.path,
- );
- }
- };
- /**
- * 选择默认菜单事件
- * @param menu
- * @param rootMenu
- */
- const handleDefaultSelect = async (
- menu: MenuRecordRaw,
- rootMenu?: MenuRecordRaw,
- ) => {
- extraMenus.value = rootMenu?.children ?? extraRootMenus.value ?? [];
- extraActiveMenu.value = menu.parents?.[parentLevel.value] ?? menu.path;
- if (preferences.sidebar.expandOnHover) {
- sidebarExtraVisible.value = extraMenus.value.length > 0;
- }
- };
- /**
- * 侧边菜单鼠标移出事件
- */
- const handleSideMouseLeave = () => {
- if (preferences.sidebar.expandOnHover) {
- return;
- }
- const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
- menus.value,
- route.path,
- );
- extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
- extraMenus.value = rootMenu?.children ?? [];
- };
- const handleMenuMouseEnter = (menu: MenuRecordRaw) => {
- if (!preferences.sidebar.expandOnHover) {
- const { findMenu } = findRootMenuByPath(menus.value, menu.path);
- extraMenus.value = findMenu?.children ?? [];
- extraActiveMenu.value = menu.parents?.[parentLevel.value] ?? menu.path;
- sidebarExtraVisible.value = extraMenus.value.length > 0;
- }
- };
- function calcExtraMenus(path: string) {
- const currentPath = route.meta?.activePath || path;
- const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
- menus.value,
- currentPath,
- parentLevel.value,
- );
- extraRootMenus.value = rootMenu?.children ?? [];
- if (rootMenuPath) defaultSubMap.set(rootMenuPath, currentPath);
- extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
- extraMenus.value = rootMenu?.children ?? [];
- if (preferences.sidebar.expandOnHover) {
- sidebarExtraVisible.value = extraMenus.value.length > 0;
- }
- }
- watch(
- () => [route.path, preferences.app.layout],
- ([path]) => {
- calcExtraMenus(path || '');
- },
- { immediate: true },
- );
- return {
- extraActiveMenu,
- extraMenus,
- handleDefaultSelect,
- handleMenuMouseEnter,
- handleMixedMenuSelect,
- handleSideMouseLeave,
- sidebarExtraVisible,
- };
- }
- export { useExtraMenu };
|