vue-vben-admin/src/layouts/default/menu/index.tsx

171 lines
4.4 KiB
TypeScript
Raw Normal View History

2020-11-23 23:24:13 +08:00
import './index.less';
2020-12-15 14:59:22 +08:00
import type { PropType, CSSProperties } from 'vue';
2020-09-28 20:19:10 +08:00
2020-12-15 14:59:22 +08:00
import { computed, defineComponent, unref, toRef } from 'vue';
2020-12-07 22:18:57 +08:00
import { BasicMenu } from '/@/components/Menu';
import { SimpleMenu } from '/@/components/SimpleMenu';
2020-11-23 23:24:13 +08:00
import { AppLogo } from '/@/components/Application';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
2020-12-15 00:13:23 +08:00
import { ScrollContainer } from '/@/components/Container';
2020-11-23 23:24:13 +08:00
import { useGo } from '/@/hooks/web/usePage';
import { useSplitMenu } from './useLayoutMenu';
import { openWindow } from '/@/utils';
2020-11-26 21:19:39 +08:00
import { propTypes } from '/@/utils/propTypes';
2020-12-07 22:18:57 +08:00
import { isUrl } from '/@/utils/is';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
2020-12-15 14:59:22 +08:00
import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '/@/hooks/web/useDesign';
2020-09-28 20:19:10 +08:00
export default defineComponent({
2020-11-24 22:59:29 +08:00
name: 'LayoutMenu',
2020-09-28 20:19:10 +08:00
props: {
2020-11-26 21:19:39 +08:00
theme: propTypes.oneOf(['light', 'dark']),
2020-09-28 20:19:10 +08:00
splitType: {
type: Number as PropType<MenuSplitTyeEnum>,
default: MenuSplitTyeEnum.NONE,
},
2020-11-26 21:19:39 +08:00
isHorizontal: propTypes.bool,
// menu Mode
2020-09-28 20:19:10 +08:00
menuMode: {
2020-11-26 21:19:39 +08:00
type: [String] as PropType<Nullable<MenuModeEnum>>,
2020-09-28 20:19:10 +08:00
default: '',
},
},
setup(props) {
2020-11-23 23:24:13 +08:00
const go = useGo();
2020-09-28 20:19:10 +08:00
2020-11-23 23:24:13 +08:00
const {
2020-11-24 22:59:29 +08:00
getMenuMode,
getMenuType,
getMenuTheme,
2020-11-23 23:24:13 +08:00
getCollapsed,
2020-12-22 23:18:50 +08:00
getCollapsedShowTitle,
2020-11-23 23:24:13 +08:00
getAccordion,
2020-12-17 00:20:29 +08:00
getIsHorizontal,
2020-12-07 22:18:57 +08:00
getIsSidebarType,
2020-11-23 23:24:13 +08:00
} = useMenuSetting();
const { getShowLogo } = useRootSetting();
2020-11-06 22:41:00 +08:00
2020-12-15 14:59:22 +08:00
const { prefixCls } = useDesign('layout-menu');
2020-12-07 22:18:57 +08:00
const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
2020-09-28 20:19:10 +08:00
2020-12-15 14:59:22 +08:00
const { getIsMobile } = useAppInject();
const getComputedMenuMode = computed(() =>
unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)
);
2020-09-28 20:19:10 +08:00
2020-11-24 22:59:29 +08:00
const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
2020-12-15 00:13:23 +08:00
const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
const getUseScroll = computed(() => {
2020-12-17 00:20:29 +08:00
return (
!unref(getIsHorizontal) &&
(unref(getIsSidebarType) ||
props.splitType === MenuSplitTyeEnum.LEFT ||
props.splitType === MenuSplitTyeEnum.NONE)
);
2020-12-15 00:13:23 +08:00
});
const getWrapperStyle = computed(
(): CSSProperties => {
return {
height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
};
}
);
2020-12-15 14:59:22 +08:00
const getLogoClass = computed(() => {
return [
`${prefixCls}-logo`,
unref(getComputedMenuTheme),
{
[`${prefixCls}--mobile`]: unref(getIsMobile),
},
];
});
2020-11-23 23:24:13 +08:00
/**
* click menu
* @param menu
*/
2020-12-15 00:13:23 +08:00
2020-12-07 22:18:57 +08:00
function handleMenuClick(path: string) {
go(path);
2020-09-28 20:19:10 +08:00
}
2020-11-23 23:24:13 +08:00
/**
* before click menu
* @param menu
*/
2020-12-07 22:18:57 +08:00
async function beforeMenuClickFn(path: string) {
if (!isUrl(path)) {
return true;
2020-09-28 20:19:10 +08:00
}
2020-12-07 22:18:57 +08:00
openWindow(path);
return false;
2020-09-28 20:19:10 +08:00
}
2020-11-23 23:24:13 +08:00
function renderHeader() {
2020-12-15 14:59:22 +08:00
if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
2020-12-07 22:18:57 +08:00
2020-09-28 20:19:10 +08:00
return (
2020-11-23 23:24:13 +08:00
<AppLogo
showTitle={!unref(getCollapsed)}
2020-12-15 14:59:22 +08:00
class={unref(getLogoClass)}
2020-11-24 22:59:29 +08:00
theme={unref(getComputedMenuTheme)}
2020-11-23 23:24:13 +08:00
/>
2020-09-28 20:19:10 +08:00
);
2020-11-23 23:24:13 +08:00
}
2020-11-06 22:41:00 +08:00
2020-12-15 00:13:23 +08:00
function renderMenu() {
const menus = unref(menusRef);
if (!menus || !menus.length) return null;
return !props.isHorizontal ? (
<SimpleMenu
items={menus}
theme={unref(getComputedMenuTheme)}
accordion={unref(getAccordion)}
collapse={unref(getCollapsed)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
onMenuClick={handleMenuClick}
/>
) : (
2020-09-28 20:19:10 +08:00
<BasicMenu
2020-11-23 23:24:13 +08:00
beforeClickFn={beforeMenuClickFn}
isHorizontal={props.isHorizontal}
2020-11-24 22:59:29 +08:00
type={unref(getMenuType)}
2020-12-22 23:18:50 +08:00
collapsedShowTitle={unref(getCollapsedShowTitle)}
showLogo={unref(getIsShowLogo)}
2020-11-24 22:59:29 +08:00
mode={unref(getComputedMenuMode)}
theme={unref(getComputedMenuTheme)}
items={menus}
2020-11-23 23:24:13 +08:00
accordion={unref(getAccordion)}
onMenuClick={handleMenuClick}
2020-12-15 00:13:23 +08:00
/>
);
}
return () => {
return (
<>
{renderHeader()}
{unref(getUseScroll) ? (
<ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer>
) : (
renderMenu()
)}
</>
2020-09-28 20:19:10 +08:00
);
};
},
});