2024-05-19 21:20:42 +08:00
|
|
|
<script lang="ts" setup>
|
2024-06-08 19:49:06 +08:00
|
|
|
import { computed } from 'vue';
|
|
|
|
|
|
|
|
import { PreferencesWidget } from '@vben/common-ui';
|
|
|
|
import { $t } from '@vben/locales';
|
2024-05-19 21:20:42 +08:00
|
|
|
import { VbenAdminLayout } from '@vben-core/layout-ui';
|
2024-06-01 23:15:29 +08:00
|
|
|
import {
|
|
|
|
preferences,
|
|
|
|
updatePreferences,
|
|
|
|
usePreferences,
|
|
|
|
} from '@vben-core/preferences';
|
2024-06-01 22:17:52 +08:00
|
|
|
import {
|
|
|
|
VbenBackTop,
|
|
|
|
// VbenFloatingButtonGroup,
|
|
|
|
VbenLogo,
|
|
|
|
} from '@vben-core/shadcn-ui';
|
2024-05-21 21:45:48 +08:00
|
|
|
import { mapTree } from '@vben-core/toolkit';
|
|
|
|
import { MenuRecordRaw } from '@vben-core/typings';
|
2024-05-19 21:20:42 +08:00
|
|
|
|
|
|
|
import { LayoutContent } from './content';
|
|
|
|
import { LayoutFooter } from './footer';
|
|
|
|
import { LayoutHeader } from './header';
|
|
|
|
import {
|
|
|
|
LayoutExtraMenu,
|
|
|
|
LayoutMenu,
|
|
|
|
LayoutMixedMenu,
|
|
|
|
useExtraMenu,
|
|
|
|
useMixedMenu,
|
|
|
|
} from './menu';
|
|
|
|
import { LayoutTabs, LayoutTabsToolbar } from './tabs';
|
|
|
|
import { Breadcrumb } from './widgets';
|
|
|
|
|
|
|
|
defineOptions({ name: 'BasicLayout' });
|
|
|
|
|
|
|
|
const { isDark, isHeaderNav, isMixedNav, isSideMixedNav, layout } =
|
2024-06-01 23:15:29 +08:00
|
|
|
usePreferences();
|
2024-05-19 21:20:42 +08:00
|
|
|
|
|
|
|
const headerMenuTheme = computed(() => {
|
|
|
|
return isDark.value ? 'dark' : 'light';
|
|
|
|
});
|
|
|
|
|
|
|
|
const theme = computed(() => {
|
2024-06-01 23:15:29 +08:00
|
|
|
const dark = isDark.value || preferences.app.semiDarkMenu;
|
2024-05-19 21:20:42 +08:00
|
|
|
return dark ? 'dark' : 'light';
|
|
|
|
});
|
|
|
|
|
|
|
|
const logoClass = computed(() => {
|
2024-06-01 23:15:29 +08:00
|
|
|
const { collapse, collapseShowTitle } = preferences.sidebar;
|
|
|
|
return collapseShowTitle && collapse && !isMixedNav.value ? 'mx-auto' : '';
|
2024-05-19 21:20:42 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const isMenuRounded = computed(() => {
|
2024-06-01 23:15:29 +08:00
|
|
|
return preferences.navigation.styleType === 'rounded';
|
2024-05-19 21:20:42 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const logoCollapse = computed(() => {
|
|
|
|
if (isHeaderNav.value || isMixedNav.value) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-06-09 12:53:38 +08:00
|
|
|
const { isMobile } = preferences.app;
|
|
|
|
const { collapse } = preferences.sidebar;
|
2024-05-19 21:20:42 +08:00
|
|
|
|
2024-06-09 12:53:38 +08:00
|
|
|
if (!collapse && isMobile) {
|
2024-05-19 21:20:42 +08:00
|
|
|
return false;
|
|
|
|
}
|
2024-06-09 12:53:38 +08:00
|
|
|
return collapse || isSideMixedNav.value;
|
2024-05-19 21:20:42 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const showHeaderNav = computed(() => {
|
|
|
|
return isHeaderNav.value || isMixedNav.value;
|
|
|
|
});
|
|
|
|
|
|
|
|
const {
|
|
|
|
extraActiveMenu,
|
|
|
|
extraMenus,
|
|
|
|
extraVisible,
|
|
|
|
handleDefaultSelect,
|
|
|
|
handleMenuMouseEnter,
|
|
|
|
handleMixedMenuSelect,
|
|
|
|
handleSideMouseLeave,
|
|
|
|
} = useExtraMenu();
|
|
|
|
|
|
|
|
const {
|
|
|
|
handleMenuSelect,
|
|
|
|
headerActive,
|
|
|
|
headerMenus,
|
|
|
|
sideActive,
|
|
|
|
sideMenus,
|
|
|
|
sideVisible,
|
|
|
|
} = useMixedMenu();
|
2024-05-21 21:45:48 +08:00
|
|
|
|
|
|
|
function wrapperMenus(menus: MenuRecordRaw[]) {
|
|
|
|
return mapTree(menus, (item) => {
|
|
|
|
return {
|
|
|
|
...item,
|
|
|
|
name: $t(item.name),
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2024-05-19 21:20:42 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<VbenAdminLayout
|
|
|
|
v-model:side-extra-visible="extraVisible"
|
2024-06-01 23:15:29 +08:00
|
|
|
:content-compact="preferences.app.contentCompact"
|
2024-06-09 13:31:43 +08:00
|
|
|
:footer-enable="preferences.footer.enable"
|
|
|
|
:footer-fixed="preferences.footer.fixed"
|
|
|
|
:header-hidden="preferences.header.hidden"
|
|
|
|
:header-mode="preferences.header.mode"
|
|
|
|
:header-visible="preferences.header.enable"
|
2024-06-01 23:15:29 +08:00
|
|
|
:is-mobile="preferences.app.isMobile"
|
2024-05-19 21:20:42 +08:00
|
|
|
:layout="layout"
|
2024-06-09 13:31:43 +08:00
|
|
|
:side-collapse="preferences.sidebar.collapse"
|
|
|
|
:side-collapse-show-title="preferences.sidebar.collapseShowTitle"
|
|
|
|
:side-expand-on-hover="preferences.sidebar.expandOnHover"
|
|
|
|
:side-extra-collapse="preferences.sidebar.extraCollapse"
|
|
|
|
:side-hidden="preferences.sidebar.hidden"
|
2024-06-01 23:15:29 +08:00
|
|
|
:side-semi-dark="preferences.app.semiDarkMenu"
|
2024-05-19 21:20:42 +08:00
|
|
|
:side-theme="theme"
|
|
|
|
:side-visible="sideVisible"
|
2024-06-01 23:15:29 +08:00
|
|
|
:side-width="preferences.sidebar.width"
|
|
|
|
:tabs-visible="preferences.tabbar.enable"
|
2024-06-09 13:31:43 +08:00
|
|
|
@side-mouse-leave="handleSideMouseLeave"
|
|
|
|
@update:side-collapse="
|
|
|
|
(value: boolean) => updatePreferences({ sidebar: { collapse: value } })
|
2024-06-09 12:53:38 +08:00
|
|
|
"
|
|
|
|
@update:side-expand-on-hover="
|
|
|
|
(value: boolean) =>
|
2024-06-09 13:31:43 +08:00
|
|
|
updatePreferences({ sidebar: { expandOnHover: value } })
|
2024-06-09 12:53:38 +08:00
|
|
|
"
|
2024-06-09 13:31:43 +08:00
|
|
|
@update:side-extra-collapse="
|
2024-06-09 12:53:38 +08:00
|
|
|
(value: boolean) =>
|
2024-06-09 13:31:43 +08:00
|
|
|
updatePreferences({ sidebar: { extraCollapse: value } })
|
2024-06-09 12:53:38 +08:00
|
|
|
"
|
2024-05-19 21:20:42 +08:00
|
|
|
@update:side-visible="
|
2024-06-09 13:31:43 +08:00
|
|
|
(value: boolean) => updatePreferences({ sidebar: { enable: value } })
|
2024-05-19 21:20:42 +08:00
|
|
|
"
|
|
|
|
>
|
2024-06-01 23:15:29 +08:00
|
|
|
<template v-if="preferences.app.showPreference" #preferences>
|
|
|
|
<PreferencesWidget />
|
2024-05-19 21:20:42 +08:00
|
|
|
</template>
|
|
|
|
|
2024-06-01 22:17:52 +08:00
|
|
|
<template #floating-button-group>
|
2024-05-19 21:20:42 +08:00
|
|
|
<VbenBackTop />
|
2024-06-01 22:17:52 +08:00
|
|
|
<!-- <VbenFloatingButtonGroup /> -->
|
2024-05-19 21:20:42 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<!-- logo -->
|
|
|
|
<template #logo>
|
|
|
|
<VbenLogo
|
2024-06-09 13:31:43 +08:00
|
|
|
:alt="preferences.app.name"
|
|
|
|
:class="logoClass"
|
2024-05-19 21:20:42 +08:00
|
|
|
:collapse="logoCollapse"
|
2024-06-01 23:15:29 +08:00
|
|
|
:src="preferences.logo.source"
|
|
|
|
:text="preferences.app.name"
|
2024-05-19 21:20:42 +08:00
|
|
|
:theme="showHeaderNav ? headerMenuTheme : theme"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<!-- 头部区域 -->
|
|
|
|
<template #header>
|
|
|
|
<LayoutHeader :theme="theme">
|
|
|
|
<template
|
2024-06-01 23:15:29 +08:00
|
|
|
v-if="!showHeaderNav && preferences.breadcrumb.enable"
|
2024-05-19 21:20:42 +08:00
|
|
|
#breadcrumb
|
|
|
|
>
|
|
|
|
<Breadcrumb
|
2024-06-01 23:15:29 +08:00
|
|
|
:hide-when-only-one="preferences.breadcrumb.hideOnlyOne"
|
|
|
|
:show-home="preferences.breadcrumb.showHome"
|
2024-06-09 13:31:43 +08:00
|
|
|
:show-icon="preferences.breadcrumb.showIcon"
|
|
|
|
:type="preferences.breadcrumb.styleType"
|
2024-05-19 21:20:42 +08:00
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<template v-if="showHeaderNav" #menu>
|
|
|
|
<LayoutMenu
|
2024-06-09 13:31:43 +08:00
|
|
|
:default-active="headerActive"
|
|
|
|
:menus="wrapperMenus(headerMenus)"
|
2024-05-19 21:20:42 +08:00
|
|
|
:rounded="isMenuRounded"
|
|
|
|
:theme="headerMenuTheme"
|
2024-06-09 13:31:43 +08:00
|
|
|
class="w-full"
|
|
|
|
mode="horizontal"
|
2024-05-19 21:20:42 +08:00
|
|
|
@select="handleMenuSelect"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<template #user-dropdown>
|
|
|
|
<slot name="user-dropdown"></slot>
|
|
|
|
</template>
|
|
|
|
<template #notification>
|
|
|
|
<slot name="notification"></slot>
|
|
|
|
</template>
|
|
|
|
</LayoutHeader>
|
|
|
|
</template>
|
|
|
|
<!-- 侧边菜单区域 -->
|
|
|
|
<template #menu>
|
|
|
|
<LayoutMenu
|
2024-06-01 23:15:29 +08:00
|
|
|
:accordion="preferences.navigation.accordion"
|
|
|
|
:collapse="preferences.sidebar.collapse"
|
2024-06-09 13:31:43 +08:00
|
|
|
:collapse-show-title="preferences.sidebar.collapseShowTitle"
|
2024-05-19 21:20:42 +08:00
|
|
|
:default-active="sideActive"
|
2024-06-09 13:31:43 +08:00
|
|
|
:menus="wrapperMenus(sideMenus)"
|
|
|
|
:rounded="isMenuRounded"
|
|
|
|
:theme="theme"
|
|
|
|
mode="vertical"
|
2024-05-19 21:20:42 +08:00
|
|
|
@select="handleMenuSelect"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<template #mixed-menu>
|
|
|
|
<LayoutMixedMenu
|
|
|
|
:active-path="extraActiveMenu"
|
2024-06-09 13:31:43 +08:00
|
|
|
:collapse="!preferences.sidebar.collapseShowTitle"
|
|
|
|
:rounded="isMenuRounded"
|
2024-05-19 21:20:42 +08:00
|
|
|
:theme="theme"
|
|
|
|
@default-select="handleDefaultSelect"
|
|
|
|
@enter="handleMenuMouseEnter"
|
2024-06-09 13:31:43 +08:00
|
|
|
@select="handleMixedMenuSelect"
|
2024-05-19 21:20:42 +08:00
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<!-- 侧边额外区域 -->
|
|
|
|
<template #side-extra>
|
|
|
|
<LayoutExtraMenu
|
2024-06-01 23:15:29 +08:00
|
|
|
:accordion="preferences.navigation.accordion"
|
|
|
|
:collapse="preferences.sidebar.extraCollapse"
|
2024-06-09 13:31:43 +08:00
|
|
|
:menus="wrapperMenus(extraMenus)"
|
|
|
|
:rounded="isMenuRounded"
|
2024-05-19 21:20:42 +08:00
|
|
|
:theme="theme"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<template #side-extra-title>
|
|
|
|
<VbenLogo
|
2024-06-01 23:15:29 +08:00
|
|
|
v-if="preferences.logo.enable"
|
2024-06-09 13:31:43 +08:00
|
|
|
:alt="preferences.app.name"
|
2024-06-01 23:15:29 +08:00
|
|
|
:text="preferences.app.name"
|
2024-05-19 21:20:42 +08:00
|
|
|
:theme="theme"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template #tabs>
|
|
|
|
<LayoutTabs
|
2024-06-01 23:15:29 +08:00
|
|
|
v-if="preferences.tabbar.enable"
|
|
|
|
:show-icon="preferences.tabbar.showIcon"
|
2024-05-19 21:20:42 +08:00
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
<template #tabs-toolbar>
|
2024-06-01 23:15:29 +08:00
|
|
|
<LayoutTabsToolbar v-if="preferences.tabbar.enable" />
|
2024-05-19 21:20:42 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<!-- 主体内容 -->
|
|
|
|
<template #content>
|
|
|
|
<LayoutContent />
|
|
|
|
</template>
|
|
|
|
<!-- 页脚 -->
|
2024-06-01 23:15:29 +08:00
|
|
|
<template v-if="preferences.footer.enable" #footer>
|
|
|
|
<LayoutFooter v-if="preferences.app.copyright">
|
|
|
|
{{ preferences.app.copyright }}
|
2024-05-19 21:20:42 +08:00
|
|
|
</LayoutFooter>
|
|
|
|
</template>
|
|
|
|
</VbenAdminLayout>
|
|
|
|
</template>
|