123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- import type { PropType } from 'vue';
- import type { Menu } from '/@/router/types';
- import { computed, defineComponent, unref, ref, onMounted, watch } from 'vue';
- import { BasicMenu } from '/@/components/Menu/index';
- import Logo from '/@/layouts/Logo.vue';
- import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
- // store
- import { appStore } from '/@/store/modules/app';
- import { menuStore } from '/@/store/modules/menu';
- import {
- getMenus,
- getFlatMenus,
- getShallowMenus,
- getChildrenMenus,
- getFlatChildrenMenus,
- getCurrentParentPath,
- } from '/@/router/menus/index';
- import { useRouter } from 'vue-router';
- import { useThrottle } from '/@/hooks/core/useThrottle';
- import { permissionStore } from '/@/store/modules/permission';
- // import { useTabs } from '/@/hooks/web/useTabs';
- // import { PageEnum } from '/@/enums/pageEnum';
- // import
- export default defineComponent({
- name: 'DefaultLayoutMenu',
- props: {
- theme: {
- type: String as PropType<string>,
- default: '',
- },
- splitType: {
- type: Number as PropType<MenuSplitTyeEnum>,
- default: MenuSplitTyeEnum.NONE,
- },
- parentMenuPath: {
- type: String as PropType<string>,
- default: '',
- },
- showSearch: {
- type: Boolean as PropType<boolean>,
- default: true,
- },
- menuMode: {
- type: [String] as PropType<MenuModeEnum | null>,
- default: '',
- },
- },
- setup(props) {
- const menusRef = ref<Menu[]>([]);
- const flatMenusRef = ref<Menu[]>([]);
- const { currentRoute, push } = useRouter();
- // const { addTab } = useTabs();
- const getProjectConfigRef = computed(() => {
- return appStore.getProjectConfig;
- });
- const getIsHorizontalRef = computed(() => {
- return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
- });
- onMounted(() => {
- genMenus();
- });
- const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
- // watch(
- // () => menuStore.getCurrentTopSplitMenuPathState,
- // async (parentPath: string) => {
- // throttleHandleSplitLeftMenu(parentPath);
- // }
- // );
- watch(
- [() => unref(currentRoute).path, () => props.splitType],
- async ([path, splitType]: [string, MenuSplitTyeEnum]) => {
- if (splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return;
- const parentPath = await getCurrentParentPath(path);
- parentPath && throttleHandleSplitLeftMenu(parentPath);
- },
- {
- immediate: true,
- }
- );
- watch(
- [() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState],
- () => {
- genMenus();
- }
- );
- watch([() => appStore.getProjectConfig.menuSetting.split], () => {
- if (props.splitType !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontalRef)) return;
- genMenus();
- });
- async function handleSplitLeftMenu(parentPath: string) {
- const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
- if (!isSplitMenu) return;
- const { splitType } = props;
- // 菜单分割模式-left
- if (splitType === MenuSplitTyeEnum.LEFT) {
- const children = await getChildrenMenus(parentPath);
- if (!children) return;
- const flatChildren = await getFlatChildrenMenus(children);
- flatMenusRef.value = flatChildren;
- menusRef.value = children;
- }
- }
- async function genMenus() {
- const isSplitMenu = unref(getProjectConfigRef).menuSetting.split;
- // 普通模式
- const { splitType } = props;
- if (splitType === MenuSplitTyeEnum.NONE || !isSplitMenu) {
- flatMenusRef.value = await getFlatMenus();
- menusRef.value = await getMenus();
- return;
- }
- // 菜单分割模式-top
- if (splitType === MenuSplitTyeEnum.TOP) {
- const parentPath = await getCurrentParentPath(unref(currentRoute).path);
- menuStore.commitCurrentTopSplitMenuPathState(parentPath);
- const shallowMenus = await getShallowMenus();
- flatMenusRef.value = shallowMenus;
- menusRef.value = shallowMenus;
- return;
- }
- }
- function handleMenuClick(menu: Menu) {
- const { path } = menu;
- if (path) {
- const { splitType } = props;
- // 菜单分割模式-top
- if (splitType === MenuSplitTyeEnum.TOP) {
- menuStore.commitCurrentTopSplitMenuPathState(path);
- }
- push(path);
- // addTab(path as PageEnum, true);
- }
- }
- async function beforeMenuClickFn(menu: Menu) {
- const { meta: { externalLink } = {} } = menu;
- if (externalLink) {
- window.open(externalLink, '_blank');
- return false;
- }
- return true;
- }
- function handleClickSearchInput() {
- if (menuStore.getCollapsedState) {
- menuStore.commitCollapsedState(false);
- }
- }
- const showSearchRef = computed(() => {
- const { showSearch, type, mode } = unref(getProjectConfigRef).menuSetting;
- return (
- showSearch &&
- props.showSearch &&
- !(type === MenuTypeEnum.MIX && mode === MenuModeEnum.HORIZONTAL)
- );
- });
- return () => {
- const {
- showLogo,
- menuSetting: { type: menuType, mode, theme, collapsed, collapsedShowTitle },
- } = unref(getProjectConfigRef);
- const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
- const isShowLogo = showLogo && isSidebarType;
- const themeData = props.theme || theme;
- return (
- <BasicMenu
- beforeClickFn={beforeMenuClickFn}
- onMenuClick={handleMenuClick}
- type={menuType}
- mode={props.menuMode || mode}
- class="layout-menu"
- collapsedShowTitle={collapsedShowTitle}
- theme={themeData}
- showLogo={isShowLogo}
- search={unref(showSearchRef) && !collapsed}
- items={unref(menusRef)}
- flatItems={unref(flatMenusRef)}
- onClickSearchInput={handleClickSearchInput}
- appendClass={props.splitType === MenuSplitTyeEnum.TOP}
- >
- {{
- header: () =>
- isShowLogo && (
- <Logo
- showTitle={!collapsed}
- class={[`layout-menu__logo`, collapsed ? 'justify-center' : '', themeData]}
- />
- ),
- }}
- </BasicMenu>
- );
- };
- },
- });
|