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

261 lines
7.5 KiB
TypeScript
Raw Normal View History

2020-11-23 23:24:13 +08:00
import './index.less';
2020-11-24 22:59:29 +08:00
import type { FunctionalComponent } from 'vue';
2020-11-25 23:20:30 +08:00
import type { Component } from '/@/components/types';
2020-11-24 22:59:29 +08:00
2020-11-24 00:22:01 +08:00
import { defineComponent, unref, computed, ref, nextTick } 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-23 23:24:13 +08:00
import { AppLogo } from '/@/components/Application';
2020-09-28 20:19:10 +08:00
import UserDropdown from './UserDropdown';
2020-11-24 22:59:29 +08:00
import LayoutMenu from '../menu';
2020-09-28 20:19:10 +08:00
import LayoutBreadcrumb from './LayoutBreadcrumb';
2020-11-24 22:59:29 +08:00
import LockAction from '../lock/LockAction';
2020-11-10 23:50:47 +08:00
import LayoutTrigger from '../LayoutTrigger';
import NoticeAction from './notice/NoticeActionItem.vue';
2020-09-28 20:19:10 +08:00
import {
RedoOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
LockOutlined,
2020-10-18 21:55:21 +08:00
BugOutlined,
2020-09-28 20:19:10 +08:00
} from '@ant-design/icons-vue';
2020-11-23 23:24:13 +08:00
import { useModal } from '/@/components/Modal';
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';
2020-11-23 23:24:13 +08:00
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
2020-11-25 23:20:30 +08:00
import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
2020-11-23 23:24:13 +08:00
import { useRouter } from 'vue-router';
2020-10-31 19:51:24 +08:00
import { errorStore } from '/@/store/modules/error';
2020-11-23 23:24:13 +08:00
import { PageEnum } from '/@/enums/pageEnum';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
2020-11-25 23:20:30 +08:00
import { AppLocalePicker } from '/@/components/Application';
import { useI18n } from '/@/hooks/web/useI18n';
2020-11-10 23:50:47 +08:00
2020-11-24 22:59:29 +08:00
interface TooltipItemProps {
title: string;
}
const TooltipItem: FunctionalComponent<TooltipItemProps> = (props, { slots }) => {
return (
<Tooltip>
{{
title: () => props.title,
default: () => slots.default?.(),
}}
</Tooltip>
);
};
2020-09-28 20:19:10 +08:00
export default defineComponent({
2020-11-23 23:24:13 +08:00
name: 'LayoutHeader',
2020-11-24 22:59:29 +08:00
props: {
fixed: {
type: Boolean,
default: false,
},
},
setup(props) {
2020-11-25 21:06:00 +08:00
let logoEl: Element | null | undefined;
2020-10-31 19:51:24 +08:00
2020-11-24 00:22:01 +08:00
const logoWidthRef = ref(200);
2020-11-25 21:06:00 +08:00
const logoRef = ref<ComponentRef>(null);
const { refreshPage } = useTabs();
2020-11-25 23:20:30 +08:00
const { t } = useI18n('layout.header');
2020-11-23 23:24:13 +08:00
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getTopMenuAlign } = useMenuSetting();
2020-11-25 23:20:30 +08:00
const { getShowLocale } = useLocaleSetting();
2020-11-23 23:24:13 +08:00
const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
const {
2020-11-24 22:59:29 +08:00
getHeaderTheme,
2020-11-23 23:24:13 +08:00
getShowRedo,
getUseLockPage,
getShowFullScreen,
getShowNotice,
getShowContent,
getShowBread,
getShowHeaderLogo,
} = useHeaderSetting();
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
useWindowSizeFn(
() => {
2020-11-24 00:22:01 +08:00
nextTick(() => {
if (!unref(getShowTopMenu)) return;
let width = 0;
if (!logoEl) {
2020-11-25 21:06:00 +08:00
logoEl = unref(logoRef)?.$el;
2020-11-24 22:59:29 +08:00
} else {
2020-11-24 00:22:01 +08:00
width += logoEl.clientWidth;
}
logoWidthRef.value = width + 80;
});
2020-10-19 22:56:10 +08:00
},
200,
{ immediate: true }
);
2020-09-28 20:19:10 +08:00
const headerClass = computed(() => {
2020-11-24 22:59:29 +08:00
const theme = unref(getHeaderTheme);
2020-09-28 20:19:10 +08:00
return theme ? `layout-header__header--${theme}` : '';
});
2020-10-18 21:55:21 +08:00
2020-11-23 23:24:13 +08:00
const getSplitType = computed(() => {
return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
});
const getMenuMode = computed(() => {
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
2020-11-06 22:41:00 +08:00
});
2020-10-18 21:55:21 +08:00
function handleToErrorList() {
2020-11-23 23:24:13 +08:00
push(PageEnum.ERROR_LOG_PAGE).then(() => {
errorStore.commitErrorListCountState(0);
});
2020-10-18 21:55:21 +08:00
}
2020-09-28 20:19:10 +08:00
function handleLockPage() {
openModal(true);
}
2020-10-31 19:51:24 +08:00
2020-11-23 23:24:13 +08:00
function renderHeaderContent() {
2020-11-24 00:22:01 +08:00
const width = unref(logoWidthRef);
2020-11-23 23:24:13 +08:00
return (
<div class="layout-header__content ">
{unref(getShowHeaderLogo) && (
2020-11-24 22:59:29 +08:00
<AppLogo class={`layout-header__logo`} ref={logoRef} theme={unref(getHeaderTheme)} />
2020-11-23 23:24:13 +08:00
)}
2020-09-28 20:19:10 +08:00
2020-11-23 23:24:13 +08:00
{unref(getShowContent) && (
<div class="layout-header__left">
{unref(getShowHeaderTrigger) && (
2020-11-24 22:59:29 +08:00
<LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
2020-11-23 23:24:13 +08:00
)}
{unref(getShowBread) && <LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />}
</div>
)}
2020-10-31 19:51:24 +08:00
2020-11-23 23:24:13 +08:00
{unref(getShowTopMenu) && (
<div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
<LayoutMenu
isHorizontal={true}
class={`justify-${unref(getTopMenuAlign)}`}
2020-11-24 22:59:29 +08:00
theme={unref(getHeaderTheme)}
2020-11-23 23:24:13 +08:00
splitType={unref(getSplitType)}
menuMode={unref(getMenuMode)}
showSearch={false}
/>
</div>
)}
</div>
);
}
2020-10-31 19:51:24 +08:00
2020-11-23 23:24:13 +08:00
function renderActionDefault(Comp: Component | any, event: Fn) {
2020-09-28 20:19:10 +08:00
return (
2020-11-25 23:20:30 +08:00
<div class="layout-header__action-item" onClick={event}>
<Comp class="layout-header__action-icon" />
2020-11-23 23:24:13 +08:00
</div>
);
}
2020-11-06 22:41:00 +08:00
2020-11-23 23:24:13 +08:00
function renderAction() {
return (
<div class={`layout-header__action`}>
{unref(getUseErrorHandle) && (
2020-11-25 23:20:30 +08:00
<TooltipItem title={t('layout.header.tooltipErrorLog')}>
2020-11-24 22:59:29 +08:00
{() => (
<Badge
count={errorStore.getErrorListCountState}
offset={[0, 10]}
dot
overflowCount={99}
>
{() => renderActionDefault(BugOutlined, handleToErrorList)}
</Badge>
)}
</TooltipItem>
2020-11-23 23:24:13 +08:00
)}
2020-09-28 20:19:10 +08:00
2020-11-23 23:24:13 +08:00
{unref(getUseLockPage) && (
2020-11-25 23:20:30 +08:00
<TooltipItem title={t('layout.header.tooltipLock')}>
2020-11-24 22:59:29 +08:00
{() => renderActionDefault(LockOutlined, handleLockPage)}
</TooltipItem>
2020-11-23 23:24:13 +08:00
)}
{unref(getShowNotice) && (
2020-11-25 23:20:30 +08:00
<TooltipItem title={t('layout.header.tooltipNotify')}>
{() => <NoticeAction />}
</TooltipItem>
2020-11-23 23:24:13 +08:00
)}
2020-10-18 21:55:21 +08:00
2020-11-23 23:24:13 +08:00
{unref(getShowRedo) && (
2020-11-25 23:20:30 +08:00
<TooltipItem title={t('layout.header.tooltipRedo')}>
2020-11-24 22:59:29 +08:00
{() => renderActionDefault(RedoOutlined, refreshPage)}
</TooltipItem>
2020-09-28 20:19:10 +08:00
)}
2020-11-23 23:24:13 +08:00
{unref(getShowFullScreen) && (
2020-11-25 23:20:30 +08:00
<TooltipItem
title={
unref(isFullscreenRef)
? t('layout.header.tooltipExitFull')
: t('layout.header.tooltipEntryFull')
}
>
2020-11-24 22:59:29 +08:00
{() => {
const Icon = !unref(isFullscreenRef) ? (
<FullscreenOutlined />
) : (
<FullscreenExitOutlined />
);
return renderActionDefault(Icon, toggleFullscreen);
2020-11-23 23:24:13 +08:00
}}
2020-11-24 22:59:29 +08:00
</TooltipItem>
2020-11-23 23:24:13 +08:00
)}
2020-11-25 23:20:30 +08:00
<UserDropdown class="layout-header__user-dropdown" />
{unref(getShowLocale) && (
<AppLocalePicker
reload={true}
showText={false}
class="layout-header__action-item locale"
/>
)}
2020-11-23 23:24:13 +08:00
</div>
);
}
function renderHeaderDefault() {
return (
<>
{renderHeaderContent()}
{renderAction()}
<LockAction onRegister={register} />
</>
);
}
return () => {
return (
2020-11-24 22:59:29 +08:00
<Layout.Header
class={['layout-header', 'flex p-0 px-4 ', unref(headerClass), { fixed: props.fixed }]}
>
2020-11-23 23:24:13 +08:00
{() => renderHeaderDefault()}
2020-09-28 20:19:10 +08:00
</Layout.Header>
);
};
},
});