perf: layout style optimization

This commit is contained in:
vben 2020-10-31 19:51:24 +08:00
parent 05980a817e
commit 7702832181
27 changed files with 201 additions and 218 deletions

2
.env
View File

@ -2,7 +2,7 @@
VITE_PORT = 3100 VITE_PORT = 3100
# spa-title # spa-title
VITE_GLOB_APP_TITLE = Vben Admin 2.0 VITE_GLOB_APP_TITLE = Vben Admin
# spa shortname # spa shortname
VITE_GLOB_APP_SHORT_NAME = vue_vben_admin_2x VITE_GLOB_APP_SHORT_NAME = vue_vben_admin_2x

View File

@ -1,3 +1,13 @@
## Wip
### ⚡ Performance Improvements
- Layout 界面布局样式调整
### 🐛 Bug Fixes
- 修复表格类型错误
## 2.0.0-rc.7 (2020-10-31) ## 2.0.0-rc.7 (2020-10-31)
### ✨ Features ### ✨ Features

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -37,7 +37,7 @@
.breadcrumb { .breadcrumb {
height: @header-height; height: @header-height;
padding-right: 20px; padding-right: 20px;
font-size: 12px; font-size: 14px;
line-height: @header-height; line-height: @header-height;
// line-height: 1; // line-height: 1;

View File

@ -66,7 +66,7 @@ export default defineComponent({
offset += 54; offset += 54;
} }
return { return {
height: `calc(100% - ${offset - 30}px)`, height: `calc(100% - ${offset - 38}px)`,
position: 'relative', position: 'relative',
overflow: 'auto', overflow: 'auto',
}; };
@ -147,6 +147,7 @@ export default defineComponent({
} }
const showTitle = computed(() => { const showTitle = computed(() => {
if (props.isTop) return true;
if (!props.isAppMenu) return true; if (!props.isAppMenu) return true;
if (!props.collapsedShowTitle) { if (!props.collapsedShowTitle) {
return !menuStore.getCollapsedState; return !menuStore.getCollapsedState;
@ -247,7 +248,6 @@ export default defineComponent({
return () => { return () => {
const { getCollapsedState } = menuStore; const { getCollapsedState } = menuStore;
const { mode } = props; const { mode } = props;
return mode === MenuModeEnum.HORIZONTAL ? ( return mode === MenuModeEnum.HORIZONTAL ? (
renderMenu() renderMenu()
) : ( ) : (

View File

@ -94,7 +94,7 @@
.ant-input { .ant-input {
color: @text-color-base; color: @text-color-base;
background: #fff; background: #fff;
border: 0; // border: 0;
outline: none; outline: none;
&:hover, &:hover,

View File

@ -4,7 +4,7 @@
color: @white; color: @white;
background: linear-gradient( background: linear-gradient(
118deg, 118deg,
rgba(@primary-color, 0.7), rgba(@primary-color, 0.8),
rgba(@primary-color, 1) rgba(@primary-color, 1)
) !important; ) !important;
border-radius: 2px; border-radius: 2px;
@ -32,6 +32,7 @@
font-size: 12px; font-size: 12px;
flex-direction: column; flex-direction: column;
line-height: 24px; line-height: 24px;
align-items: center;
} }
& > li[role='menuitem']:not(.ant-menu-submenu) { & > li[role='menuitem']:not(.ant-menu-submenu) {
@ -93,6 +94,8 @@
} }
&-bg__sidebar-hor { &-bg__sidebar-hor {
overflow: hidden;
&.ant-menu-horizontal { &.ant-menu-horizontal {
display: flex; display: flex;
border: 0; border: 0;
@ -105,23 +108,16 @@
&.ant-menu-light { &.ant-menu-light {
.ant-menu-item { .ant-menu-item {
&.basic-menu-item__level1 { &.basic-menu-item__level1 {
height: 38px; height: @header-height;
line-height: 38px; line-height: @header-height;
} }
} }
.ant-menu-item:hover,
.ant-menu-submenu:hover, .ant-menu-submenu:hover,
.ant-menu-item-active,
.ant-menu-submenu-active,
.ant-menu-item-open, .ant-menu-item-open,
.ant-menu-submenu-open, .ant-menu-submenu-open,
.ant-menu-item-selected, .ant-menu-item-selected,
.ant-menu-submenu-selected { .ant-menu-submenu-selected,
color: @primary-color !important;
border-bottom: 3px solid @primary-color;
}
.ant-menu-item:hover, .ant-menu-item:hover,
.ant-menu-item-active, .ant-menu-item-active,
.ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open,
@ -261,10 +257,13 @@
} }
&.ant-menu-light { &.ant-menu-light {
overflow-x: hidden;
border-right: none;
.basic-menu-item__level1 { .basic-menu-item__level1 {
&.top-active-menu { &.top-active-menu {
color: @primary-color; color: @primary-color;
border-bottom: 6px solid @primary-color; border-bottom: 3px solid @primary-color;
} }
} }
@ -306,16 +305,9 @@
} }
&-light { &-light {
border-right: 1px solid rgba(221, 221, 221, 0.6);
.ant-layout-sider-trigger { .ant-layout-sider-trigger {
color: @text-color-base; color: @text-color-base;
background: @trigger-light-bg-color; border-top: 1px solid @border-color-light;
&:hover {
color: @text-color-base;
background: @trigger-light-hover-bg-color;
}
} }
} }
} }

View File

@ -54,6 +54,10 @@ export const basicProps = {
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: true, default: true,
}, },
isTop: {
type: Boolean as PropType<boolean>,
default: false,
},
beforeClickFn: { beforeClickFn: {
type: Function as PropType<Fn>, type: Function as PropType<Fn>,
default: null, default: null,

View File

@ -2,10 +2,15 @@
@import './input.less'; @import './input.less';
@import './btn.less'; @import './btn.less';
// TODO beta.11 fix
.ant-col { .ant-col {
width: 100%; width: 100%;
} }
// .ant-form-item-label {
// text-align: unset;
// }
// ================================= // =================================
// ==============descriptions======= // ==============descriptions=======
// ================================= // =================================

View File

@ -36,7 +36,8 @@ input::-ms-reveal {
} }
body { body {
font-family: 'Microsoft YaHei,微软雅黑,Arial,sans-serif,Helvetica Neue,Helvetica,Pingfang SC,Hiragino Sans GB'; // font-family: 'Microsoft YaHei,微软雅黑,Arial,sans-serif,Helvetica Neue,Helvetica,Pingfang SC,Hiragino Sans GB';
font-family: '-apple-system,BlinkMacSystemFont,segoe ui,Roboto,helvetica neue,Arial,noto sans,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol,noto color emoji';
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
line-height: 1.428571429; // 20/14 line-height: 1.428571429; // 20/14
@ -149,7 +150,7 @@ object {
} }
.ant-layout { .ant-layout {
background: #f1f1f6; background: #f0f2f5;
&-content { &-content {
position: relative; position: relative;

View File

@ -5,11 +5,11 @@
} }
// TODO 滚动条样式-待修改 // TODO 滚动条样式-待修改
::-webkit-scrollbar-track { // ::-webkit-scrollbar-track {
// background: rgba(0, 0, 0, 0.06); // // background: rgba(0, 0, 0, 0.06);
// border-radius: 2px; // // border-radius: 2px;
// box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); // // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
} // }
/* 滚动条滑块 */ /* 滚动条滑块 */
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {

View File

@ -3,13 +3,13 @@
@import 'breakpoint'; @import 'breakpoint';
// tabs // tabs
@multiple-height: 36px; @multiple-height: 30px;
// headers // headers
@header-height: 36px; @header-height: 46px;
// logo width // logo width
@logo-width: 40px; @logo-width: 36px;
// //
@sider-drag-z-index: 200; @sider-drag-z-index: 200;
@ -18,4 +18,4 @@
// app menu // app menu
// left-menu // left-menu
@app-menu-item-height: 44px; @app-menu-item-height: 42px;

View File

@ -1,19 +1,24 @@
<template> <template>
<div class="app-logo" @click="handleGoHome"> <div class="app-logo" @click="handleGoHome" :style="wrapStyle">
<img :src="logo" /> <img :src="logo" />
<div v-if="show" class="logo-title ml-1 mt-1 ellipsis">{{ globSetting.title }}</div> <div v-if="show" class="logo-title ml-2 ellipsis">{{ globSetting.title }}</div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, ref, watch } from 'vue'; import { computed, defineComponent, PropType, ref, watch } from 'vue';
// hooks // hooks
import { useSetting } from '/@/hooks/core/useSetting'; import { useSetting } from '/@/hooks/core/useSetting';
import { PageEnum } from '/@/enums/pageEnum';
import logo from '/@/assets/images/logo.png';
import { useTimeout } from '/@/hooks/core/useTimeout'; import { useTimeout } from '/@/hooks/core/useTimeout';
import { useGo } from '/@/hooks/web/usePage'; import { useGo } from '/@/hooks/web/usePage';
import { PageEnum } from '/@/enums/pageEnum';
import { MenuTypeEnum } from '../enums/menuEnum';
import logo from '/@/assets/images/logo.png';
import { menuStore } from '../store/modules/menu';
import { appStore } from '../store/modules/app';
export default defineComponent({ export default defineComponent({
name: 'Logo', name: 'Logo',
props: { props: {
@ -44,11 +49,24 @@
} }
); );
const wrapStyle = computed(() => {
const { getCollapsedState } = menuStore;
const {
menuSetting: { menuWidth, type },
} = appStore.getProjectConfig;
const miniWidth = { minWidth: `${menuWidth}px` };
if (type !== MenuTypeEnum.SIDEBAR) {
return miniWidth;
}
return getCollapsedState ? {} : miniWidth;
});
return { return {
handleGoHome, handleGoHome,
globSetting, globSetting,
show: showRef, show: showRef,
logo, logo,
wrapStyle,
}; };
}, },
}); });
@ -59,12 +77,13 @@
.app-logo { .app-logo {
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 16px;
cursor: pointer; cursor: pointer;
.logo-title { .logo-title {
display: none; display: none;
font-family: Georgia, serif;
font-size: 16px; font-size: 16px;
font-weight: 400;
.respond-to(medium,{ .respond-to(medium,{
display: block; display: block;
}); });

View File

@ -4,7 +4,6 @@ import { Layout } from 'ant-design-vue';
import { ContentEnum } from '/@/enums/appEnum'; import { ContentEnum } from '/@/enums/appEnum';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
// import { RouterView } from 'vue-router';
import PageLayout from '/@/layouts/page/index'; import PageLayout from '/@/layouts/page/index';
export default defineComponent({ export default defineComponent({
name: 'DefaultLayoutContent', name: 'DefaultLayoutContent',
@ -15,9 +14,7 @@ export default defineComponent({
const wrapClass = contentMode === ContentEnum.FULL ? 'full' : 'fixed'; const wrapClass = contentMode === ContentEnum.FULL ? 'full' : 'fixed';
return ( return (
<Layout.Content class={`layout-content ${wrapClass} `}> <Layout.Content class={`layout-content ${wrapClass} `}>
{{ {() => <PageLayout />}
default: () => <PageLayout />,
}}
</Layout.Content> </Layout.Content>
); );
}; };

View File

@ -1,11 +1,12 @@
import { defineComponent, unref, computed, ref } from 'vue'; import { defineComponent, unref, computed, ref } from 'vue';
import { Layout, Tooltip, Badge } from 'ant-design-vue'; import { Layout, Tooltip, Badge } from 'ant-design-vue';
import Logo from '/@/layouts/Logo.vue'; import Logo from '/@/layouts/Logo.vue';
import UserDropdown from './UserDropdown'; import UserDropdown from './UserDropdown';
import LayoutMenu from './LayoutMenu'; import LayoutMenu from './LayoutMenu';
import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import LayoutBreadcrumb from './LayoutBreadcrumb'; import LayoutBreadcrumb from './LayoutBreadcrumb';
import LockAction from './actions/LockActionItem';
import NoticeAction from './actions/notice/NoticeActionItem.vue';
import { import {
RedoOutlined, RedoOutlined,
FullscreenExitOutlined, FullscreenExitOutlined,
@ -14,19 +15,24 @@ import {
LockOutlined, LockOutlined,
BugOutlined, BugOutlined,
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import { useFullscreen } from '/@/hooks/web/useFullScreen'; import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs'; import { useTabs } from '/@/hooks/web/useTabs';
import { GITHUB_URL } from '/@/settings/siteSetting';
import LockAction from './actions/LockActionItem';
import { useModal } from '/@/components/Modal/index';
import { errorStore } from '/@/store/modules/error';
import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
import NoticeAction from './actions/notice/NoticeActionItem.vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useModal } from '/@/components/Modal/index';
import { appStore } from '/@/store/modules/app';
import { errorStore } from '/@/store/modules/error';
import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { GITHUB_URL } from '/@/settings/siteSetting';
export default defineComponent({ export default defineComponent({
name: 'DefaultLayoutHeader', name: 'DefaultLayoutHeader',
setup() { setup() {
const widthRef = ref(200); const widthRef = ref(200);
let logoEl: Element | null;
const { refreshPage } = useTabs(); const { refreshPage } = useTabs();
const { push } = useRouter(); const { push } = useRouter();
const [register, { openModal }] = useModal(); const [register, { openModal }] = useModal();
@ -35,6 +41,7 @@ export default defineComponent({
const getProjectConfigRef = computed(() => { const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig; return appStore.getProjectConfig;
}); });
const showTopMenu = computed(() => { const showTopMenu = computed(() => {
const getProjectConfig = unref(getProjectConfigRef); const getProjectConfig = unref(getProjectConfigRef);
const { const {
@ -43,7 +50,6 @@ export default defineComponent({
return mode === MenuModeEnum.HORIZONTAL || splitMenu; return mode === MenuModeEnum.HORIZONTAL || splitMenu;
}); });
let logoEl: Element | null;
useWindowSizeFn( useWindowSizeFn(
() => { () => {
if (!unref(showTopMenu)) return; if (!unref(showTopMenu)) return;
@ -80,6 +86,7 @@ export default defineComponent({
function handleLockPage() { function handleLockPage() {
openModal(true); openModal(true);
} }
return () => { return () => {
const getProjectConfig = unref(getProjectConfigRef); const getProjectConfig = unref(getProjectConfigRef);
const { const {
@ -99,7 +106,9 @@ export default defineComponent({
} = getProjectConfig; } = getProjectConfig;
const isSidebarType = menuType === MenuTypeEnum.SIDEBAR; const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
const width = unref(widthRef); const width = unref(widthRef);
return ( return (
<Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}> <Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}>
{() => ( {() => (
@ -112,10 +121,12 @@ export default defineComponent({
)} )}
{unref(showTopMenu) && ( {unref(showTopMenu) && (
<div <div
class={[`layout-header__menu `, `justify-${topMenuAlign}`]} class={[`layout-header__menu `]}
style={{ width: `calc(100% - ${unref(width)}px)` }} style={{ width: `calc(100% - ${unref(width)}px)` }}
> >
<LayoutMenu <LayoutMenu
isTop={true}
class={`justify-${topMenuAlign}`}
theme={headerTheme} theme={headerTheme}
splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE} splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE}
menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null} menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null}

View File

@ -45,6 +45,10 @@ export default defineComponent({
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: true, default: true,
}, },
isTop: {
type: Boolean as PropType<boolean>,
default: false,
},
menuMode: { menuMode: {
type: [String] as PropType<MenuModeEnum | null>, type: [String] as PropType<MenuModeEnum | null>,
default: '', default: '',
@ -199,6 +203,7 @@ export default defineComponent({
flatItems={unref(flatMenusRef)} flatItems={unref(flatMenusRef)}
onClickSearchInput={handleClickSearchInput} onClickSearchInput={handleClickSearchInput}
appendClass={props.splitType === MenuSplitTyeEnum.TOP} appendClass={props.splitType === MenuSplitTyeEnum.TOP}
isTop={props.isTop}
> >
{{ {{
header: () => header: () =>

View File

@ -7,7 +7,7 @@ import { menuStore } from '/@/store/modules/menu';
// import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png'; // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
// import lightMiniImg from '/@/assets/images/sidebar/light-mini.png'; // import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
import darkImg from '/@/assets/images/sidebar/dark.png'; import darkImg from '/@/assets/images/sidebar/dark.png';
import lightImg from '/@/assets/images/sidebar/light.png'; // import lightImg from '/@/assets/images/sidebar/light.png';
import { appStore } from '/@/store/modules/app'; import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
@ -39,15 +39,16 @@ export default defineComponent({
// const collapse = unref(collapseRef); // const collapse = unref(collapseRef);
const theme = unref(getProjectConfigRef).menuSetting.theme; const theme = unref(getProjectConfigRef).menuSetting.theme;
if (theme === MenuThemeEnum.LIGHT) {
// bg = lightImg;
return {};
}
let bg = ''; let bg = '';
if (theme === MenuThemeEnum.DARK) { if (theme === MenuThemeEnum.DARK) {
// bg = collapse ? darkMiniIMg : darkImg; // bg = collapse ? darkMiniIMg : darkImg;
bg = darkImg; bg = darkImg;
} }
if (theme === MenuThemeEnum.LIGHT) {
bg = lightImg;
// bg = collapse ? lightMiniImg : lightImg;
}
return { return {
'background-image': `url(${bg})`, 'background-image': `url(${bg})`,
}; };

View File

@ -21,6 +21,11 @@ export default defineComponent({
return appStore.getProjectConfig; return appStore.getProjectConfig;
}); });
const getUserInfo = computed(() => {
const { realName = '', desc } = userStore.getUserInfoState || {};
return { realName, desc };
});
/** /**
* @description: 退 * @description: 退
*/ */
@ -41,10 +46,20 @@ export default defineComponent({
openDoc(); openDoc();
} }
} }
const getUserInfo = computed(() => {
const { realName = '', desc } = userStore.getUserInfoState || {}; function renderItem({ icon, text, key }: { icon: string; text: string; key: string }) {
return { realName, desc }; return (
}); <Menu.Item key={key}>
{() => (
<span class="flex items-center">
<Icon icon={icon} class="mr-1" />
<span>{text}</span>
</span>
)}
</Menu.Item>
);
}
return () => { return () => {
const { realName } = unref(getUserInfo); const { realName } = unref(getUserInfo);
const { const {
@ -65,28 +80,13 @@ export default defineComponent({
<Menu slot="overlay" onClick={handleMenuClick}> <Menu slot="overlay" onClick={handleMenuClick}>
{() => ( {() => (
<> <>
{showDoc && ( {showDoc && renderItem({ key: 'doc', text: '文档', icon: 'gg:loadbar-doc' })}
<Menu.Item key="doc">
{() => (
<span class="flex items-center">
<Icon icon="gg:loadbar-doc" class="mr-1" />
<span></span>
</span>
)}
</Menu.Item>
)}
{showDoc && <Divider />} {showDoc && <Divider />}
{renderItem({
<Menu.Item key="loginOut"> key: 'loginOut',
{() => ( text: '退出系统',
<> icon: 'ant-design:poweroff-outlined',
<span class="flex items-center"> })}
<Icon icon="ant-design:poweroff-outlined" class="mr-1" />
<span>退</span>
</span>
</>
)}
</Menu.Item>
</> </>
)} )}
</Menu> </Menu>

View File

@ -1,9 +1,9 @@
.lock-modal { .lock-modal {
&__entry { &__entry {
position: relative; position: relative;
width: 500px; // width: 500px;
height: 240px; height: 240px;
padding: 80px 30px 0 30px; padding: 130px 30px 60px 30px;
background: #fff; background: #fff;
border-radius: 10px; border-radius: 10px;
} }

View File

@ -24,7 +24,7 @@ export default defineComponent({
schemas: [ schemas: [
{ {
field: 'password', field: 'password',
label: '锁屏密码', label: '',
component: 'InputPassword', component: 'InputPassword',
componentProps: { componentProps: {
placeholder: '请输入锁屏密码', placeholder: '请输入锁屏密码',

View File

@ -1,12 +1,6 @@
@import (reference) '../../design/index.less'; @import (reference) '../../design/index.less';
.default-layout { .default-layout {
// .ant-menu-submenu .ant-menu-sub {
// transition: none !important;
// // transition: background 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s,
// // padding 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s !important;
// }
&__content { &__content {
position: relative; position: relative;
@ -72,6 +66,10 @@
.layout-sidebar { .layout-sidebar {
background-size: 100% 100%; background-size: 100% 100%;
&:not(.ant-layout-sider-dark) {
border-right: 1px solid @border-color-light;
}
.ant-layout-sider-zero-width-trigger { .ant-layout-sider-zero-width-trigger {
top: 40%; top: 40%;
z-index: 10; z-index: 10;
@ -99,25 +97,13 @@
} }
} }
.setting-button {
top: 45%;
right: 0;
padding: 8px;
border-radius: 6px 0 0 6px;
svg {
width: 1em;
height: 1em;
}
}
&__tabs { &__tabs {
z-index: 10; z-index: 10;
height: @multiple-height; height: @multiple-height;
padding: 0; padding: 0;
line-height: @multiple-height; line-height: @multiple-height;
background: @border-color-shallow-light; background: @border-color-shallow-light;
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.08); box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.12);
} }
} }
@ -194,11 +180,17 @@
} }
} }
.ant-layout-header { .ant-layout-header:not(.default-layout__tabs) {
height: @header-height; height: @header-height;
line-height: @header-height; line-height: @header-height;
} }
.ant-layout-header.default-layout__tabs {
height: @multiple-height + 2;
line-height: @multiple-height + 2;
background: @white;
}
.layout-header { .layout-header {
display: flex; display: flex;
height: @header-height; height: @header-height;
@ -351,22 +343,20 @@
} }
&__menu { &__menu {
// display: flex;
margin-left: 20px; margin-left: 20px;
overflow: hidden; overflow: hidden;
align-items: center; align-items: center;
// flex-grow: 1;
} }
&__user-dropdown { &__user-dropdown {
height: 52px; height: @header-height;
padding: 0 0 0 10px; padding: 0 0 0 10px;
} }
} }
.user-dropdown { .user-dropdown {
display: flex; display: flex;
height: 100%; padding-right: 10px;
font-size: 12px; font-size: 12px;
cursor: pointer; cursor: pointer;
align-items: center; align-items: center;
@ -374,49 +364,12 @@
img { img {
width: 26px; width: 26px;
height: 26px; height: 26px;
margin-right: 16px; margin-right: 12px;
} }
&__header { &__header {
border-radius: 50%; border-radius: 50%;
} }
&__divider {
width: 1px;
height: 30px;
margin-right: 20px;
background: #c6d9ee;
}
&__exit {
margin-top: -40px;
font-size: 12px;
color: #c6d9ee;
text-align: center;
> section {
height: 20px;
}
}
&__info {
display: flex;
margin-right: 12px;
flex-direction: column;
> section {
line-height: 1.8;
}
}
&__name {
font-size: 12px;
}
&__desc {
font-size: 12px;
.text-truncate();
}
} }
.layout-breadcrumb { .layout-breadcrumb {
@ -425,8 +378,8 @@
} }
.ant-layout-sider-trigger { .ant-layout-sider-trigger {
height: 30px; height: 36px;
line-height: 30px; line-height: 36px;
} }
.hide-title { .hide-title {

View File

@ -1,4 +1,4 @@
import { defineComponent, unref, onMounted, computed } from 'vue'; import { defineComponent, unref, computed } from 'vue';
import { Layout, BackTop } from 'ant-design-vue'; import { Layout, BackTop } from 'ant-design-vue';
import LayoutHeader from './LayoutHeader'; import LayoutHeader from './LayoutHeader';
@ -30,6 +30,7 @@ export default defineComponent({
const getProjectConfigRef = computed(() => { const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig; return appStore.getProjectConfig;
}); });
const getLockMainScrollStateRef = computed(() => { const getLockMainScrollStateRef = computed(() => {
return appStore.getLockMainScrollState; return appStore.getLockMainScrollState;
}); });
@ -40,6 +41,7 @@ export default defineComponent({
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
return show; return show;
}); });
const isShowMixHeaderRef = computed(() => { const isShowMixHeaderRef = computed(() => {
const { const {
menuSetting: { type }, menuSetting: { type },
@ -54,12 +56,6 @@ export default defineComponent({
return show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent); return show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent);
}); });
// const { currentRoute } = useRouter();
onMounted(() => {
// Each refresh will request the latest user information, if you dont need it, you can delete it
// userStore.getUserInfoAction({ userId: userStore.getUserInfoState.userId });
});
// Get project configuration // Get project configuration
// const { getFullContent } = useFullContent(currentRoute); // const { getFullContent } = useFullContent(currentRoute);
function getTarget(): any { function getTarget(): any {
@ -68,6 +64,7 @@ export default defineComponent({
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
return document.querySelector(`.default-layout__${fixed ? 'main' : 'content'}`); return document.querySelector(`.default-layout__${fixed ? 'main' : 'content'}`);
} }
return () => { return () => {
const { getPageLoading, getLockInfo } = appStore; const { getPageLoading, getLockInfo } = appStore;
const { const {
@ -77,10 +74,11 @@ export default defineComponent({
multiTabsSetting: { show: showTabs }, multiTabsSetting: { show: showTabs },
headerSetting: { fixed }, headerSetting: { fixed },
} = unref(getProjectConfigRef); } = unref(getProjectConfigRef);
// const fixedHeaderCls = fixed ? ('fixed' + getLockMainScrollState ? ' lock' : '') : '';
const fixedHeaderCls = fixed const fixedHeaderCls = fixed
? 'fixed' + (unref(getLockMainScrollStateRef) ? ' lock' : '') ? 'fixed' + (unref(getLockMainScrollStateRef) ? ' lock' : '')
: ''; : '';
const { isLock } = getLockInfo; const { isLock } = getLockInfo;
return ( return (
<Layout class="default-layout relative"> <Layout class="default-layout relative">

View File

@ -1,8 +1,6 @@
@import (reference) '../../../design/index.less'; @import (reference) '../../../design/index.less';
.multiple-tabs { .multiple-tabs {
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.ant-tabs-small { .ant-tabs-small {
height: @multiple-height; height: @multiple-height;
} }
@ -13,7 +11,7 @@
margin: 0; margin: 0;
background: @white; background: @white;
border: 0; border: 0;
box-shadow: 0 4px 26px 1px rgba(0, 0, 0, 0.08); box-shadow: none;
.ant-tabs-nav-container { .ant-tabs-nav-container {
height: @multiple-height; height: @multiple-height;
@ -22,17 +20,26 @@
.ant-tabs-tab { .ant-tabs-tab {
height: calc(@multiple-height - 2px); height: calc(@multiple-height - 2px);
font-size: 14px;
line-height: calc(@multiple-height - 2px); line-height: calc(@multiple-height - 2px);
color: @text-color-call-out; color: @text-color-call-out;
background: @white; background: @white;
border: 1px solid darken(@border-color-light, 6%); border: 1px solid darken(@border-color-light, 8%);
border-radius: 2px 2px 0 0; border-radius: none !important;
transition: none; transition: none;
.ant-tabs-close-x { .ant-tabs-close-x {
// display: none; width: 12px;
height: 12px;
font-size: 12px;
color: inherit; color: inherit;
transition: none;
&:hover {
svg {
width: 0.8em;
transition: all 0.1s;
}
}
} }
&:hover { &:hover {
@ -50,37 +57,12 @@
svg { svg {
fill: @text-color-base; fill: @text-color-base;
} }
&::before {
position: absolute;
top: -2px;
right: 0;
left: 0;
height: 4px;
background-color: @primary-color;
border-radius: 16px 6px 0 0;
content: '';
transform: scaleX(0);
transform-origin: bottom right;
}
&:hover::before {
transform: scaleX(1);
transition: transform 0.3s ease;
transform-origin: bottom left;
}
} }
.ant-tabs-tab-active { .ant-tabs-tab-active {
height: calc(@multiple-height - 3px);
color: @white; color: @white;
background: linear-gradient( background: fade(@primary-color, 100%);
118deg,
rgba(@primary-color, 0.8),
rgba(@primary-color, 1)
) !important;
border: 0; border: 0;
box-shadow: 0 0 6px 1px rgba(@primary-color, 0.7);
&::before { &::before {
display: none; display: none;
@ -88,6 +70,7 @@
svg { svg {
fill: @white; fill: @white;
width: 0.7em;
} }
} }
} }
@ -95,12 +78,6 @@
.ant-tabs-nav > div:nth-child(1) { .ant-tabs-nav > div:nth-child(1) {
padding: 0 10px; padding: 0 10px;
} }
.ant-tabs-tab-prev,
.ant-tabs-tab-next {
color: @border-color-dark;
background: @white;
}
} }
.ant-tabs-tab:not(.ant-tabs-tab-active) { .ant-tabs-tab:not(.ant-tabs-tab-active) {
@ -108,20 +85,19 @@
font-size: 12px; font-size: 12px;
svg { svg {
width: 0.8em; width: 0.6em;
}
}
&:hover {
.anticon-close {
color: @white;
} }
} }
} }
} }
.ant-tabs-extra-content { .ant-tabs-extra-content {
line-height: @multiple-height; margin-top: 2px;
line-height: @multiple-height !important;
}
.ant-dropdown-trigger {
display: inline-flex;
} }
.multiple-tabs-content { .multiple-tabs-content {
@ -133,7 +109,7 @@
color: @primary-color; color: @primary-color;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); // box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
span[role='img'] { span[role='img'] {
transform: rotate(90deg); transform: rotate(90deg);
@ -143,8 +119,10 @@
&__content { &__content {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
padding-left: 10px; height: @multiple-height - 2;
padding-left: 0;
margin-left: -10px; margin-left: -10px;
font-size: 12px;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
} }

View File

@ -159,7 +159,7 @@ export default defineComponent({
size="small" size="small"
animated={false} animated={false}
hideAdd={true} hideAdd={true}
tabBarGutter={2} tabBarGutter={4}
activeKey={unref(activeKeyRef)} activeKey={unref(activeKeyRef)}
onChange={handleChange} onChange={handleChange}
onEdit={handleEdit} onEdit={handleEdit}

View File

@ -28,13 +28,21 @@
.setting-button { .setting-button {
position: absolute; position: absolute;
top: 45%;
right: 0;
z-index: 10; z-index: 10;
display: flex; display: flex;
// padding: 10px; padding: 10px;
color: @white; color: @white;
cursor: pointer; cursor: pointer;
background: @primary-color; background: @primary-color;
border-radius: 6px 0 0 6px;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
svg {
width: 1em;
height: 1em;
}
} }
</style> </style>

View File

@ -9,14 +9,15 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { useFrameKeepAlive } from './useFrameKeepAlive';
import FramePage from '/@/views/sys/iframe/index.vue'; import FramePage from '/@/views/sys/iframe/index.vue';
import { useFrameKeepAlive } from './useFrameKeepAlive';
export default defineComponent({ export default defineComponent({
name: 'FrameLayout', name: 'FrameLayout',
components: { FramePage }, components: { FramePage },
setup() { setup() {
const { hasRenderFrame, showIframe, getFramePages } = useFrameKeepAlive(); return { ...useFrameKeepAlive() };
return { hasRenderFrame, showIframe, getFramePages };
}, },
}); });
</script> </script>

View File

@ -55,7 +55,7 @@ const setting: ProjectConfig = {
// 是否显示搜索框 // 是否显示搜索框
showSearch: true, showSearch: true,
// 菜单宽度 // 菜单宽度
menuWidth: 180, menuWidth: 200,
// 菜单模式 // 菜单模式
mode: MenuModeEnum.INLINE, mode: MenuModeEnum.INLINE,
// 菜单类型 // 菜单类型
@ -65,7 +65,7 @@ const setting: ProjectConfig = {
// 分割菜单 // 分割菜单
split: false, split: false,
// 顶部菜单布局 // 顶部菜单布局
topMenuAlign: 'start', topMenuAlign: 'center',
}, },
// 消息配置 // 消息配置
messageSetting: { messageSetting: {
@ -83,7 +83,7 @@ const setting: ProjectConfig = {
// 开启快速操作 // 开启快速操作
showQuick: true, showQuick: true,
// 显示icon // 显示icon
showIcon: true, showIcon: false,
// 标签页缓存最大数量 // 标签页缓存最大数量
max: 12, max: 12,
}, },