vue-vben-admin/src/layouts/default/header/LayoutHeader.tsx

260 lines
8.6 KiB
TypeScript
Raw Normal View History

2020-10-19 22:56:10 +08:00
import { defineComponent, unref, computed, ref } from 'vue';
2020-10-31 19:51:24 +08:00
2020-10-18 21:55:21 +08:00
import { Layout, Tooltip, Badge } from 'ant-design-vue';
2020-11-10 23:50:47 +08:00
import Logo from '/@/layouts/logo/index.vue';
2020-09-28 20:19:10 +08:00
import UserDropdown from './UserDropdown';
2020-11-10 23:50:47 +08:00
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu';
2020-09-28 20:19:10 +08:00
import LayoutBreadcrumb from './LayoutBreadcrumb';
2020-11-10 23:50:47 +08:00
import LockAction from './LockActionItem';
import LayoutTrigger from '../LayoutTrigger';
import NoticeAction from './notice/NoticeActionItem.vue';
2020-09-28 20:19:10 +08:00
import {
RedoOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
GithubFilled,
LockOutlined,
2020-10-18 21:55:21 +08:00
BugOutlined,
2020-09-28 20:19:10 +08:00
} from '@ant-design/icons-vue';
2020-10-31 19:51:24 +08:00
2020-09-28 20:19:10 +08:00
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
import { useRouter } from 'vue-router';
2020-11-12 22:20:15 +08:00
import { useModal } from '/@/components/Modal';
2020-10-31 19:51:24 +08:00
import { appStore } from '/@/store/modules/app';
import { errorStore } from '/@/store/modules/error';
2020-11-06 22:41:00 +08:00
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
2020-10-31 19:51:24 +08:00
import { GITHUB_URL } from '/@/settings/siteSetting';
2020-11-10 23:50:47 +08:00
import './index.less';
2020-09-28 20:19:10 +08:00
export default defineComponent({
name: 'DefaultLayoutHeader',
setup() {
2020-10-19 22:56:10 +08:00
const widthRef = ref(200);
2020-10-31 19:51:24 +08:00
let logoEl: Element | null;
const { refreshPage } = useTabs();
const { push } = useRouter();
2020-09-28 20:19:10 +08:00
const [register, { openModal }] = useModal();
const { toggleFullscreen, isFullscreenRef } = useFullscreen();
2020-10-19 22:56:10 +08:00
2020-09-28 20:19:10 +08:00
const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig;
});
2020-10-31 19:51:24 +08:00
2020-10-19 22:56:10 +08:00
const showTopMenu = computed(() => {
const getProjectConfig = unref(getProjectConfigRef);
const {
menuSetting: { mode, split: splitMenu },
} = getProjectConfig;
return mode === MenuModeEnum.HORIZONTAL || splitMenu;
});
useWindowSizeFn(
() => {
if (!unref(showTopMenu)) return;
let width = 0;
if (!logoEl) {
logoEl = document.querySelector('.layout-header__logo');
}
if (logoEl) {
width += logoEl.clientWidth;
}
widthRef.value = width + 60;
},
200,
{ immediate: true }
);
2020-09-28 20:19:10 +08:00
function goToGithub() {
window.open(GITHUB_URL, '__blank');
}
const headerClass = computed(() => {
const theme = unref(getProjectConfigRef).headerSetting.theme;
return theme ? `layout-header__header--${theme}` : '';
});
2020-10-18 21:55:21 +08:00
2020-11-06 22:41:00 +08:00
const showHeaderTrigger = computed(() => {
const { show, trigger, hidden, type } = unref(getProjectConfigRef).menuSetting;
if (type === MenuTypeEnum.TOP_MENU || !show || !hidden) return false;
2020-11-06 22:41:00 +08:00
return trigger === TriggerEnum.HEADER;
});
2020-10-18 21:55:21 +08:00
function handleToErrorList() {
errorStore.commitErrorListCountState(0);
push('/exception/error-log');
2020-10-18 21:55:21 +08:00
}
2020-09-28 20:19:10 +08:00
/**
* @description:
*/
function handleLockPage() {
openModal(true);
}
2020-10-31 19:51:24 +08:00
2020-09-28 20:19:10 +08:00
return () => {
const getProjectConfig = unref(getProjectConfigRef);
const {
2020-10-18 21:55:21 +08:00
useErrorHandle,
2020-09-28 20:19:10 +08:00
showLogo,
2020-11-06 22:41:00 +08:00
multiTabsSetting: { show: showTab },
2020-10-21 21:15:06 +08:00
headerSetting: {
theme: headerTheme,
useLockPage,
showRedo,
showGithub,
showFullScreen,
showNotice,
},
2020-09-28 20:19:10 +08:00
menuSetting: { mode, type: menuType, split: splitMenu, topMenuAlign },
showBreadCrumb,
showBreadCrumbIcon,
2020-09-28 20:19:10 +08:00
} = getProjectConfig;
const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
2020-10-31 19:51:24 +08:00
2020-10-19 22:56:10 +08:00
const width = unref(widthRef);
2020-10-31 19:51:24 +08:00
const showLeft =
(mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu) ||
unref(showHeaderTrigger);
2020-09-28 20:19:10 +08:00
return (
2020-10-11 00:05:29 +08:00
<Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}>
2020-09-28 20:19:10 +08:00
{() => (
<>
2020-10-11 00:05:29 +08:00
<div class="layout-header__content ">
2020-11-06 22:41:00 +08:00
{showLogo && !isSidebarType && (
<Logo class={`layout-header__logo`} theme={headerTheme} />
2020-09-28 20:19:10 +08:00
)}
2020-11-06 22:41:00 +08:00
{showLeft && (
<div class="layout-header__left">
{unref(showHeaderTrigger) && (
<LayoutTrigger theme={headerTheme} sider={false} />
)}
{mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
<LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
)}
</div>
)}
2020-11-06 22:41:00 +08:00
2020-10-19 22:56:10 +08:00
{unref(showTopMenu) && (
<div
2020-10-31 19:51:24 +08:00
class={[`layout-header__menu `]}
2020-10-19 22:56:10 +08:00
style={{ width: `calc(100% - ${unref(width)}px)` }}
>
2020-09-28 20:19:10 +08:00
<LayoutMenu
2020-10-31 19:51:24 +08:00
isTop={true}
class={`justify-${topMenuAlign}`}
2020-09-28 20:19:10 +08:00
theme={headerTheme}
splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE}
menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null}
showSearch={false}
/>
</div>
)}
</div>
<div class={`layout-header__action`}>
2020-10-18 21:55:21 +08:00
{useErrorHandle && (
<Tooltip>
{{
title: () => '错误日志',
default: () => (
<Badge
count={errorStore.getErrorListCountState}
offset={[0, 10]}
dot
2020-10-18 21:55:21 +08:00
overflowCount={99}
>
{() => (
<div class={`layout-header__action-item`} onClick={handleToErrorList}>
<BugOutlined class={`layout-header__action-icon`} />
</div>
)}
</Badge>
),
}}
</Tooltip>
)}
2020-09-28 20:19:10 +08:00
{showGithub && (
<Tooltip>
{{
title: () => 'github',
default: () => (
<div class={`layout-header__action-item`} onClick={goToGithub}>
<GithubFilled class={`layout-header__action-icon`} />
</div>
),
}}
</Tooltip>
)}
2020-10-18 21:55:21 +08:00
{useLockPage && (
2020-09-28 20:19:10 +08:00
<Tooltip>
{{
title: () => '锁定屏幕',
default: () => (
<div class={`layout-header__action-item`} onClick={handleLockPage}>
<LockOutlined class={`layout-header__action-icon`} />
</div>
),
}}
</Tooltip>
)}
2020-10-21 21:15:06 +08:00
{showNotice && (
<div>
<Tooltip>
{{
title: () => '消息通知',
default: () => <NoticeAction />,
2020-10-21 21:15:06 +08:00
}}
</Tooltip>
</div>
)}
2020-11-06 22:41:00 +08:00
{showRedo && showTab && (
2020-09-28 20:19:10 +08:00
<Tooltip>
{{
title: () => '刷新',
default: () => (
<div class={`layout-header__action-item`} onClick={refreshPage}>
<RedoOutlined class={`layout-header__action-icon`} />
</div>
),
}}
</Tooltip>
)}
{showFullScreen && (
<Tooltip>
{{
title: () => (unref(isFullscreenRef) ? '退出全屏' : '全屏'),
default: () => {
const Icon: any = !unref(isFullscreenRef) ? (
<FullscreenOutlined />
) : (
<FullscreenExitOutlined />
);
return (
<div class={`layout-header__action-item`} onClick={toggleFullscreen}>
<Icon class={`layout-header__action-icon`} />
</div>
);
},
}}
</Tooltip>
)}
<UserDropdown class={`layout-header__user-dropdown`} />
</div>
<LockAction onRegister={register} />
</>
)}
</Layout.Header>
);
};
},
});