Commit 77028321816f00799cc3f70d3f0d6bde27c34522

Authored by vben
1 parent 05980a81

perf: layout style optimization

... ... @@ -2,7 +2,7 @@
2 2 VITE_PORT = 3100
3 3  
4 4 # spa-title
5   -VITE_GLOB_APP_TITLE = Vben Admin 2.0
  5 +VITE_GLOB_APP_TITLE = Vben Admin
6 6  
7 7 # spa shortname
8 8 VITE_GLOB_APP_SHORT_NAME = vue_vben_admin_2x
... ...
CHANGELOG.zh_CN.md
  1 +## Wip
  2 +
  3 +### ⚡ Performance Improvements
  4 +
  5 +- Layout 界面布局样式调整
  6 +
  7 +### 🐛 Bug Fixes
  8 +
  9 +- 修复表格类型错误
  10 +
1 11 ## 2.0.0-rc.7 (2020-10-31)
2 12  
3 13 ### ✨ Features
... ...
src/assets/images/logo.png

14.3 KB | W: | H:

27.6 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/components/Breadcrumb/Breadcrumb.vue
... ... @@ -37,7 +37,7 @@
37 37 .breadcrumb {
38 38 height: @header-height;
39 39 padding-right: 20px;
40   - font-size: 12px;
  40 + font-size: 14px;
41 41 line-height: @header-height;
42 42 // line-height: 1;
43 43  
... ...
src/components/Menu/src/BasicMenu.tsx
... ... @@ -66,7 +66,7 @@ export default defineComponent({
66 66 offset += 54;
67 67 }
68 68 return {
69   - height: `calc(100% - ${offset - 30}px)`,
  69 + height: `calc(100% - ${offset - 38}px)`,
70 70 position: 'relative',
71 71 overflow: 'auto',
72 72 };
... ... @@ -147,6 +147,7 @@ export default defineComponent({
147 147 }
148 148  
149 149 const showTitle = computed(() => {
  150 + if (props.isTop) return true;
150 151 if (!props.isAppMenu) return true;
151 152 if (!props.collapsedShowTitle) {
152 153 return !menuStore.getCollapsedState;
... ... @@ -247,7 +248,6 @@ export default defineComponent({
247 248 return () => {
248 249 const { getCollapsedState } = menuStore;
249 250 const { mode } = props;
250   -
251 251 return mode === MenuModeEnum.HORIZONTAL ? (
252 252 renderMenu()
253 253 ) : (
... ...
src/components/Menu/src/SearchInput.vue
... ... @@ -94,7 +94,7 @@
94 94 .ant-input {
95 95 color: @text-color-base;
96 96 background: #fff;
97   - border: 0;
  97 + // border: 0;
98 98 outline: none;
99 99  
100 100 &:hover,
... ...
src/components/Menu/src/index.less
... ... @@ -4,7 +4,7 @@
4 4 color: @white;
5 5 background: linear-gradient(
6 6 118deg,
7   - rgba(@primary-color, 0.7),
  7 + rgba(@primary-color, 0.8),
8 8 rgba(@primary-color, 1)
9 9 ) !important;
10 10 border-radius: 2px;
... ... @@ -32,6 +32,7 @@
32 32 font-size: 12px;
33 33 flex-direction: column;
34 34 line-height: 24px;
  35 + align-items: center;
35 36 }
36 37  
37 38 & > li[role='menuitem']:not(.ant-menu-submenu) {
... ... @@ -93,6 +94,8 @@
93 94 }
94 95  
95 96 &-bg__sidebar-hor {
  97 + overflow: hidden;
  98 +
96 99 &.ant-menu-horizontal {
97 100 display: flex;
98 101 border: 0;
... ... @@ -105,23 +108,16 @@
105 108 &.ant-menu-light {
106 109 .ant-menu-item {
107 110 &.basic-menu-item__level1 {
108   - height: 38px;
109   - line-height: 38px;
  111 + height: @header-height;
  112 + line-height: @header-height;
110 113 }
111 114 }
112 115  
113   - .ant-menu-item:hover,
114 116 .ant-menu-submenu:hover,
115   - .ant-menu-item-active,
116   - .ant-menu-submenu-active,
117 117 .ant-menu-item-open,
118 118 .ant-menu-submenu-open,
119 119 .ant-menu-item-selected,
120   - .ant-menu-submenu-selected {
121   - color: @primary-color !important;
122   - border-bottom: 3px solid @primary-color;
123   - }
124   -
  120 + .ant-menu-submenu-selected,
125 121 .ant-menu-item:hover,
126 122 .ant-menu-item-active,
127 123 .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open,
... ... @@ -261,10 +257,13 @@
261 257 }
262 258  
263 259 &.ant-menu-light {
  260 + overflow-x: hidden;
  261 + border-right: none;
  262 +
264 263 .basic-menu-item__level1 {
265 264 &.top-active-menu {
266 265 color: @primary-color;
267   - border-bottom: 6px solid @primary-color;
  266 + border-bottom: 3px solid @primary-color;
268 267 }
269 268 }
270 269  
... ... @@ -306,16 +305,9 @@
306 305 }
307 306  
308 307 &-light {
309   - border-right: 1px solid rgba(221, 221, 221, 0.6);
310   -
311 308 .ant-layout-sider-trigger {
312 309 color: @text-color-base;
313   - background: @trigger-light-bg-color;
314   -
315   - &:hover {
316   - color: @text-color-base;
317   - background: @trigger-light-hover-bg-color;
318   - }
  310 + border-top: 1px solid @border-color-light;
319 311 }
320 312 }
321 313 }
... ...
src/components/Menu/src/props.ts
... ... @@ -54,6 +54,10 @@ export const basicProps = {
54 54 type: Boolean as PropType<boolean>,
55 55 default: true,
56 56 },
  57 + isTop: {
  58 + type: Boolean as PropType<boolean>,
  59 + default: false,
  60 + },
57 61 beforeClickFn: {
58 62 type: Function as PropType<Fn>,
59 63 default: null,
... ...
src/design/ant/index.less
... ... @@ -2,10 +2,15 @@
2 2 @import './input.less';
3 3 @import './btn.less';
4 4  
  5 +// TODO beta.11 fix
5 6 .ant-col {
6 7 width: 100%;
7 8 }
8 9  
  10 +// .ant-form-item-label {
  11 +// text-align: unset;
  12 +// }
  13 +
9 14 // =================================
10 15 // ==============descriptions=======
11 16 // =================================
... ...
src/design/index.less
... ... @@ -36,7 +36,8 @@ input::-ms-reveal {
36 36 }
37 37  
38 38 body {
39   - font-family: 'Microsoft YaHei,微软雅黑,Arial,sans-serif,Helvetica Neue,Helvetica,Pingfang SC,Hiragino Sans GB';
  39 + // font-family: 'Microsoft YaHei,微软雅黑,Arial,sans-serif,Helvetica Neue,Helvetica,Pingfang SC,Hiragino Sans GB';
  40 + 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';
40 41 font-style: normal;
41 42 font-weight: normal;
42 43 line-height: 1.428571429; // 20/14
... ... @@ -149,7 +150,7 @@ object {
149 150 }
150 151  
151 152 .ant-layout {
152   - background: #f1f1f6;
  153 + background: #f0f2f5;
153 154  
154 155 &-content {
155 156 position: relative;
... ...
src/design/public.less
... ... @@ -5,11 +5,11 @@
5 5 }
6 6  
7 7 // TODO 滚动条样式-待修改
8   -::-webkit-scrollbar-track {
9   - // background: rgba(0, 0, 0, 0.06);
10   - // border-radius: 2px;
11   - // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
12   -}
  8 +// ::-webkit-scrollbar-track {
  9 +// // background: rgba(0, 0, 0, 0.06);
  10 +// // border-radius: 2px;
  11 +// // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
  12 +// }
13 13  
14 14 /* 滚动条滑块 */
15 15 ::-webkit-scrollbar-thumb {
... ...
src/design/var/index.less
... ... @@ -3,13 +3,13 @@
3 3 @import 'breakpoint';
4 4  
5 5 // tabs
6   -@multiple-height: 36px;
  6 +@multiple-height: 30px;
7 7  
8 8 // headers
9   -@header-height: 36px;
  9 +@header-height: 46px;
10 10  
11 11 // logo width
12   -@logo-width: 40px;
  12 +@logo-width: 36px;
13 13  
14 14 //
15 15 @sider-drag-z-index: 200;
... ... @@ -18,4 +18,4 @@
18 18 // app menu
19 19  
20 20 // left-menu
21   -@app-menu-item-height: 44px;
  21 +@app-menu-item-height: 42px;
... ...
src/layouts/Logo.vue
1 1 <template>
2   - <div class="app-logo" @click="handleGoHome">
  2 + <div class="app-logo" @click="handleGoHome" :style="wrapStyle">
3 3 <img :src="logo" />
4   - <div v-if="show" class="logo-title ml-1 mt-1 ellipsis">{{ globSetting.title }}</div>
  4 + <div v-if="show" class="logo-title ml-2 ellipsis">{{ globSetting.title }}</div>
5 5 </div>
6 6 </template>
7 7 <script lang="ts">
8   - import { defineComponent, PropType, ref, watch } from 'vue';
  8 + import { computed, defineComponent, PropType, ref, watch } from 'vue';
9 9 // hooks
10 10 import { useSetting } from '/@/hooks/core/useSetting';
  11 + import { useTimeout } from '/@/hooks/core/useTimeout';
  12 + import { useGo } from '/@/hooks/web/usePage';
11 13  
12 14 import { PageEnum } from '/@/enums/pageEnum';
  15 + import { MenuTypeEnum } from '../enums/menuEnum';
  16 +
13 17 import logo from '/@/assets/images/logo.png';
14   - import { useTimeout } from '/@/hooks/core/useTimeout';
15   - import { useGo } from '/@/hooks/web/usePage';
  18 +
  19 + import { menuStore } from '../store/modules/menu';
  20 + import { appStore } from '../store/modules/app';
16 21  
17 22 export default defineComponent({
18 23 name: 'Logo',
... ... @@ -44,11 +49,24 @@
44 49 }
45 50 );
46 51  
  52 + const wrapStyle = computed(() => {
  53 + const { getCollapsedState } = menuStore;
  54 + const {
  55 + menuSetting: { menuWidth, type },
  56 + } = appStore.getProjectConfig;
  57 + const miniWidth = { minWidth: `${menuWidth}px` };
  58 + if (type !== MenuTypeEnum.SIDEBAR) {
  59 + return miniWidth;
  60 + }
  61 + return getCollapsedState ? {} : miniWidth;
  62 + });
  63 +
47 64 return {
48 65 handleGoHome,
49 66 globSetting,
50 67 show: showRef,
51 68 logo,
  69 + wrapStyle,
52 70 };
53 71 },
54 72 });
... ... @@ -59,12 +77,13 @@
59 77 .app-logo {
60 78 display: flex;
61 79 align-items: center;
  80 + padding-left: 16px;
62 81 cursor: pointer;
63 82  
64 83 .logo-title {
65 84 display: none;
66   - font-family: Georgia, serif;
67 85 font-size: 16px;
  86 + font-weight: 400;
68 87 .respond-to(medium,{
69 88 display: block;
70 89 });
... ...
src/layouts/default/LayoutContent.tsx
... ... @@ -4,7 +4,6 @@ import { Layout } from &#39;ant-design-vue&#39;;
4 4  
5 5 import { ContentEnum } from '/@/enums/appEnum';
6 6 import { appStore } from '/@/store/modules/app';
7   -// import { RouterView } from 'vue-router';
8 7 import PageLayout from '/@/layouts/page/index';
9 8 export default defineComponent({
10 9 name: 'DefaultLayoutContent',
... ... @@ -15,9 +14,7 @@ export default defineComponent({
15 14 const wrapClass = contentMode === ContentEnum.FULL ? 'full' : 'fixed';
16 15 return (
17 16 <Layout.Content class={`layout-content ${wrapClass} `}>
18   - {{
19   - default: () => <PageLayout />,
20   - }}
  17 + {() => <PageLayout />}
21 18 </Layout.Content>
22 19 );
23 20 };
... ...
src/layouts/default/LayoutHeader.tsx
1 1 import { defineComponent, unref, computed, ref } from 'vue';
  2 +
2 3 import { Layout, Tooltip, Badge } from 'ant-design-vue';
3 4 import Logo from '/@/layouts/Logo.vue';
4 5 import UserDropdown from './UserDropdown';
5 6 import LayoutMenu from './LayoutMenu';
6   -import { appStore } from '/@/store/modules/app';
7   -import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
8 7 import LayoutBreadcrumb from './LayoutBreadcrumb';
  8 +import LockAction from './actions/LockActionItem';
  9 +import NoticeAction from './actions/notice/NoticeActionItem.vue';
9 10 import {
10 11 RedoOutlined,
11 12 FullscreenExitOutlined,
... ... @@ -14,19 +15,24 @@ import {
14 15 LockOutlined,
15 16 BugOutlined,
16 17 } from '@ant-design/icons-vue';
  18 +
17 19 import { useFullscreen } from '/@/hooks/web/useFullScreen';
18 20 import { useTabs } from '/@/hooks/web/useTabs';
19   -import { GITHUB_URL } from '/@/settings/siteSetting';
20   -import LockAction from './actions/LockActionItem';
21   -import { useModal } from '/@/components/Modal/index';
22   -import { errorStore } from '/@/store/modules/error';
23 21 import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
24   -import NoticeAction from './actions/notice/NoticeActionItem.vue';
25 22 import { useRouter } from 'vue-router';
  23 +import { useModal } from '/@/components/Modal/index';
  24 +
  25 +import { appStore } from '/@/store/modules/app';
  26 +import { errorStore } from '/@/store/modules/error';
  27 +
  28 +import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
  29 +import { GITHUB_URL } from '/@/settings/siteSetting';
26 30 export default defineComponent({
27 31 name: 'DefaultLayoutHeader',
28 32 setup() {
29 33 const widthRef = ref(200);
  34 + let logoEl: Element | null;
  35 +
30 36 const { refreshPage } = useTabs();
31 37 const { push } = useRouter();
32 38 const [register, { openModal }] = useModal();
... ... @@ -35,6 +41,7 @@ export default defineComponent({
35 41 const getProjectConfigRef = computed(() => {
36 42 return appStore.getProjectConfig;
37 43 });
  44 +
38 45 const showTopMenu = computed(() => {
39 46 const getProjectConfig = unref(getProjectConfigRef);
40 47 const {
... ... @@ -43,7 +50,6 @@ export default defineComponent({
43 50 return mode === MenuModeEnum.HORIZONTAL || splitMenu;
44 51 });
45 52  
46   - let logoEl: Element | null;
47 53 useWindowSizeFn(
48 54 () => {
49 55 if (!unref(showTopMenu)) return;
... ... @@ -80,6 +86,7 @@ export default defineComponent({
80 86 function handleLockPage() {
81 87 openModal(true);
82 88 }
  89 +
83 90 return () => {
84 91 const getProjectConfig = unref(getProjectConfigRef);
85 92 const {
... ... @@ -99,7 +106,9 @@ export default defineComponent({
99 106 } = getProjectConfig;
100 107  
101 108 const isSidebarType = menuType === MenuTypeEnum.SIDEBAR;
  109 +
102 110 const width = unref(widthRef);
  111 +
103 112 return (
104 113 <Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}>
105 114 {() => (
... ... @@ -112,10 +121,12 @@ export default defineComponent({
112 121 )}
113 122 {unref(showTopMenu) && (
114 123 <div
115   - class={[`layout-header__menu `, `justify-${topMenuAlign}`]}
  124 + class={[`layout-header__menu `]}
116 125 style={{ width: `calc(100% - ${unref(width)}px)` }}
117 126 >
118 127 <LayoutMenu
  128 + isTop={true}
  129 + class={`justify-${topMenuAlign}`}
119 130 theme={headerTheme}
120 131 splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE}
121 132 menuMode={splitMenu ? MenuModeEnum.HORIZONTAL : null}
... ...
src/layouts/default/LayoutMenu.tsx
... ... @@ -45,6 +45,10 @@ export default defineComponent({
45 45 type: Boolean as PropType<boolean>,
46 46 default: true,
47 47 },
  48 + isTop: {
  49 + type: Boolean as PropType<boolean>,
  50 + default: false,
  51 + },
48 52 menuMode: {
49 53 type: [String] as PropType<MenuModeEnum | null>,
50 54 default: '',
... ... @@ -199,6 +203,7 @@ export default defineComponent({
199 203 flatItems={unref(flatMenusRef)}
200 204 onClickSearchInput={handleClickSearchInput}
201 205 appendClass={props.splitType === MenuSplitTyeEnum.TOP}
  206 + isTop={props.isTop}
202 207 >
203 208 {{
204 209 header: () =>
... ...
src/layouts/default/LayoutSideBar.tsx
... ... @@ -7,7 +7,7 @@ import { menuStore } from &#39;/@/store/modules/menu&#39;;
7 7 // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
8 8 // import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
9 9 import darkImg from '/@/assets/images/sidebar/dark.png';
10   -import lightImg from '/@/assets/images/sidebar/light.png';
  10 +// import lightImg from '/@/assets/images/sidebar/light.png';
11 11 import { appStore } from '/@/store/modules/app';
12 12 import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
13 13 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
... ... @@ -39,15 +39,16 @@ export default defineComponent({
39 39 // const collapse = unref(collapseRef);
40 40  
41 41 const theme = unref(getProjectConfigRef).menuSetting.theme;
  42 + if (theme === MenuThemeEnum.LIGHT) {
  43 + // bg = lightImg;
  44 + return {};
  45 + }
42 46 let bg = '';
43 47 if (theme === MenuThemeEnum.DARK) {
44 48 // bg = collapse ? darkMiniIMg : darkImg;
45 49 bg = darkImg;
46 50 }
47   - if (theme === MenuThemeEnum.LIGHT) {
48   - bg = lightImg;
49   - // bg = collapse ? lightMiniImg : lightImg;
50   - }
  51 +
51 52 return {
52 53 'background-image': `url(${bg})`,
53 54 };
... ...
src/layouts/default/UserDropdown.tsx
... ... @@ -21,6 +21,11 @@ export default defineComponent({
21 21 return appStore.getProjectConfig;
22 22 });
23 23  
  24 + const getUserInfo = computed(() => {
  25 + const { realName = '', desc } = userStore.getUserInfoState || {};
  26 + return { realName, desc };
  27 + });
  28 +
24 29 /**
25 30 * @description: 退出登录
26 31 */
... ... @@ -41,10 +46,20 @@ export default defineComponent({
41 46 openDoc();
42 47 }
43 48 }
44   - const getUserInfo = computed(() => {
45   - const { realName = '', desc } = userStore.getUserInfoState || {};
46   - return { realName, desc };
47   - });
  49 +
  50 + function renderItem({ icon, text, key }: { icon: string; text: string; key: string }) {
  51 + return (
  52 + <Menu.Item key={key}>
  53 + {() => (
  54 + <span class="flex items-center">
  55 + <Icon icon={icon} class="mr-1" />
  56 + <span>{text}</span>
  57 + </span>
  58 + )}
  59 + </Menu.Item>
  60 + );
  61 + }
  62 +
48 63 return () => {
49 64 const { realName } = unref(getUserInfo);
50 65 const {
... ... @@ -65,28 +80,13 @@ export default defineComponent({
65 80 <Menu slot="overlay" onClick={handleMenuClick}>
66 81 {() => (
67 82 <>
68   - {showDoc && (
69   - <Menu.Item key="doc">
70   - {() => (
71   - <span class="flex items-center">
72   - <Icon icon="gg:loadbar-doc" class="mr-1" />
73   - <span>文档</span>
74   - </span>
75   - )}
76   - </Menu.Item>
77   - )}
  83 + {showDoc && renderItem({ key: 'doc', text: '文档', icon: 'gg:loadbar-doc' })}
78 84 {showDoc && <Divider />}
79   -
80   - <Menu.Item key="loginOut">
81   - {() => (
82   - <>
83   - <span class="flex items-center">
84   - <Icon icon="ant-design:poweroff-outlined" class="mr-1" />
85   - <span>退出系统</span>
86   - </span>
87   - </>
88   - )}
89   - </Menu.Item>
  85 + {renderItem({
  86 + key: 'loginOut',
  87 + text: '退出系统',
  88 + icon: 'ant-design:poweroff-outlined',
  89 + })}
90 90 </>
91 91 )}
92 92 </Menu>
... ...
src/layouts/default/actions/LockActionItem.less
1 1 .lock-modal {
2 2 &__entry {
3 3 position: relative;
4   - width: 500px;
  4 + // width: 500px;
5 5 height: 240px;
6   - padding: 80px 30px 0 30px;
  6 + padding: 130px 30px 60px 30px;
7 7 background: #fff;
8 8 border-radius: 10px;
9 9 }
... ...
src/layouts/default/actions/LockActionItem.tsx
... ... @@ -24,7 +24,7 @@ export default defineComponent({
24 24 schemas: [
25 25 {
26 26 field: 'password',
27   - label: '锁屏密码',
  27 + label: '',
28 28 component: 'InputPassword',
29 29 componentProps: {
30 30 placeholder: '请输入锁屏密码',
... ...
src/layouts/default/index.less
1 1 @import (reference) '../../design/index.less';
2 2  
3 3 .default-layout {
4   - // .ant-menu-submenu .ant-menu-sub {
5   - // transition: none !important;
6   - // // transition: background 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s,
7   - // // padding 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s !important;
8   - // }
9   -
10 4 &__content {
11 5 position: relative;
12 6  
... ... @@ -72,6 +66,10 @@
72 66 .layout-sidebar {
73 67 background-size: 100% 100%;
74 68  
  69 + &:not(.ant-layout-sider-dark) {
  70 + border-right: 1px solid @border-color-light;
  71 + }
  72 +
75 73 .ant-layout-sider-zero-width-trigger {
76 74 top: 40%;
77 75 z-index: 10;
... ... @@ -99,25 +97,13 @@
99 97 }
100 98 }
101 99  
102   - .setting-button {
103   - top: 45%;
104   - right: 0;
105   - padding: 8px;
106   - border-radius: 6px 0 0 6px;
107   -
108   - svg {
109   - width: 1em;
110   - height: 1em;
111   - }
112   - }
113   -
114 100 &__tabs {
115 101 z-index: 10;
116 102 height: @multiple-height;
117 103 padding: 0;
118 104 line-height: @multiple-height;
119 105 background: @border-color-shallow-light;
120   - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.08);
  106 + box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.12);
121 107 }
122 108 }
123 109  
... ... @@ -194,11 +180,17 @@
194 180 }
195 181 }
196 182  
197   -.ant-layout-header {
  183 +.ant-layout-header:not(.default-layout__tabs) {
198 184 height: @header-height;
199 185 line-height: @header-height;
200 186 }
201 187  
  188 +.ant-layout-header.default-layout__tabs {
  189 + height: @multiple-height + 2;
  190 + line-height: @multiple-height + 2;
  191 + background: @white;
  192 +}
  193 +
202 194 .layout-header {
203 195 display: flex;
204 196 height: @header-height;
... ... @@ -351,22 +343,20 @@
351 343 }
352 344  
353 345 &__menu {
354   - // display: flex;
355 346 margin-left: 20px;
356 347 overflow: hidden;
357 348 align-items: center;
358   - // flex-grow: 1;
359 349 }
360 350  
361 351 &__user-dropdown {
362   - height: 52px;
  352 + height: @header-height;
363 353 padding: 0 0 0 10px;
364 354 }
365 355 }
366 356  
367 357 .user-dropdown {
368 358 display: flex;
369   - height: 100%;
  359 + padding-right: 10px;
370 360 font-size: 12px;
371 361 cursor: pointer;
372 362 align-items: center;
... ... @@ -374,49 +364,12 @@
374 364 img {
375 365 width: 26px;
376 366 height: 26px;
377   - margin-right: 16px;
  367 + margin-right: 12px;
378 368 }
379 369  
380 370 &__header {
381 371 border-radius: 50%;
382 372 }
383   -
384   - &__divider {
385   - width: 1px;
386   - height: 30px;
387   - margin-right: 20px;
388   - background: #c6d9ee;
389   - }
390   -
391   - &__exit {
392   - margin-top: -40px;
393   - font-size: 12px;
394   - color: #c6d9ee;
395   - text-align: center;
396   -
397   - > section {
398   - height: 20px;
399   - }
400   - }
401   -
402   - &__info {
403   - display: flex;
404   - margin-right: 12px;
405   - flex-direction: column;
406   -
407   - > section {
408   - line-height: 1.8;
409   - }
410   - }
411   -
412   - &__name {
413   - font-size: 12px;
414   - }
415   -
416   - &__desc {
417   - font-size: 12px;
418   - .text-truncate();
419   - }
420 373 }
421 374  
422 375 .layout-breadcrumb {
... ... @@ -425,8 +378,8 @@
425 378 }
426 379  
427 380 .ant-layout-sider-trigger {
428   - height: 30px;
429   - line-height: 30px;
  381 + height: 36px;
  382 + line-height: 36px;
430 383 }
431 384  
432 385 .hide-title {
... ...
src/layouts/default/index.tsx
1   -import { defineComponent, unref, onMounted, computed } from 'vue';
  1 +import { defineComponent, unref, computed } from 'vue';
2 2 import { Layout, BackTop } from 'ant-design-vue';
3 3 import LayoutHeader from './LayoutHeader';
4 4  
... ... @@ -30,6 +30,7 @@ export default defineComponent({
30 30 const getProjectConfigRef = computed(() => {
31 31 return appStore.getProjectConfig;
32 32 });
  33 +
33 34 const getLockMainScrollStateRef = computed(() => {
34 35 return appStore.getLockMainScrollState;
35 36 });
... ... @@ -40,6 +41,7 @@ export default defineComponent({
40 41 } = unref(getProjectConfigRef);
41 42 return show;
42 43 });
  44 +
43 45 const isShowMixHeaderRef = computed(() => {
44 46 const {
45 47 menuSetting: { type },
... ... @@ -54,12 +56,6 @@ export default defineComponent({
54 56 return show && mode !== MenuModeEnum.HORIZONTAL && !unref(getFullContent);
55 57 });
56 58  
57   - // const { currentRoute } = useRouter();
58   - onMounted(() => {
59   - // Each refresh will request the latest user information, if you don’t need it, you can delete it
60   - // userStore.getUserInfoAction({ userId: userStore.getUserInfoState.userId });
61   - });
62   -
63 59 // Get project configuration
64 60 // const { getFullContent } = useFullContent(currentRoute);
65 61 function getTarget(): any {
... ... @@ -68,6 +64,7 @@ export default defineComponent({
68 64 } = unref(getProjectConfigRef);
69 65 return document.querySelector(`.default-layout__${fixed ? 'main' : 'content'}`);
70 66 }
  67 +
71 68 return () => {
72 69 const { getPageLoading, getLockInfo } = appStore;
73 70 const {
... ... @@ -77,10 +74,11 @@ export default defineComponent({
77 74 multiTabsSetting: { show: showTabs },
78 75 headerSetting: { fixed },
79 76 } = unref(getProjectConfigRef);
80   - // const fixedHeaderCls = fixed ? ('fixed' + getLockMainScrollState ? ' lock' : '') : '';
  77 +
81 78 const fixedHeaderCls = fixed
82 79 ? 'fixed' + (unref(getLockMainScrollStateRef) ? ' lock' : '')
83 80 : '';
  81 +
84 82 const { isLock } = getLockInfo;
85 83 return (
86 84 <Layout class="default-layout relative">
... ...
src/layouts/default/multitabs/index.less
1 1 @import (reference) '../../../design/index.less';
2 2  
3 3 .multiple-tabs {
4   - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
5   -
6 4 .ant-tabs-small {
7 5 height: @multiple-height;
8 6 }
... ... @@ -13,7 +11,7 @@
13 11 margin: 0;
14 12 background: @white;
15 13 border: 0;
16   - box-shadow: 0 4px 26px 1px rgba(0, 0, 0, 0.08);
  14 + box-shadow: none;
17 15  
18 16 .ant-tabs-nav-container {
19 17 height: @multiple-height;
... ... @@ -22,17 +20,26 @@
22 20  
23 21 .ant-tabs-tab {
24 22 height: calc(@multiple-height - 2px);
25   - font-size: 14px;
26 23 line-height: calc(@multiple-height - 2px);
27 24 color: @text-color-call-out;
28 25 background: @white;
29   - border: 1px solid darken(@border-color-light, 6%);
30   - border-radius: 2px 2px 0 0;
  26 + border: 1px solid darken(@border-color-light, 8%);
  27 + border-radius: none !important;
31 28 transition: none;
32 29  
33 30 .ant-tabs-close-x {
34   - // display: none;
  31 + width: 12px;
  32 + height: 12px;
  33 + font-size: 12px;
35 34 color: inherit;
  35 + transition: none;
  36 +
  37 + &:hover {
  38 + svg {
  39 + width: 0.8em;
  40 + transition: all 0.1s;
  41 + }
  42 + }
36 43 }
37 44  
38 45 &:hover {
... ... @@ -50,37 +57,12 @@
50 57 svg {
51 58 fill: @text-color-base;
52 59 }
53   -
54   - &::before {
55   - position: absolute;
56   - top: -2px;
57   - right: 0;
58   - left: 0;
59   - height: 4px;
60   - background-color: @primary-color;
61   - border-radius: 16px 6px 0 0;
62   - content: '';
63   - transform: scaleX(0);
64   - transform-origin: bottom right;
65   - }
66   -
67   - &:hover::before {
68   - transform: scaleX(1);
69   - transition: transform 0.3s ease;
70   - transform-origin: bottom left;
71   - }
72 60 }
73 61  
74 62 .ant-tabs-tab-active {
75   - height: calc(@multiple-height - 3px);
76 63 color: @white;
77   - background: linear-gradient(
78   - 118deg,
79   - rgba(@primary-color, 0.8),
80   - rgba(@primary-color, 1)
81   - ) !important;
  64 + background: fade(@primary-color, 100%);
82 65 border: 0;
83   - box-shadow: 0 0 6px 1px rgba(@primary-color, 0.7);
84 66  
85 67 &::before {
86 68 display: none;
... ... @@ -88,6 +70,7 @@
88 70  
89 71 svg {
90 72 fill: @white;
  73 + width: 0.7em;
91 74 }
92 75 }
93 76 }
... ... @@ -95,12 +78,6 @@
95 78 .ant-tabs-nav > div:nth-child(1) {
96 79 padding: 0 10px;
97 80 }
98   -
99   - .ant-tabs-tab-prev,
100   - .ant-tabs-tab-next {
101   - color: @border-color-dark;
102   - background: @white;
103   - }
104 81 }
105 82  
106 83 .ant-tabs-tab:not(.ant-tabs-tab-active) {
... ... @@ -108,20 +85,19 @@
108 85 font-size: 12px;
109 86  
110 87 svg {
111   - width: 0.8em;
112   - }
113   - }
114   -
115   - &:hover {
116   - .anticon-close {
117   - color: @white;
  88 + width: 0.6em;
118 89 }
119 90 }
120 91 }
121 92 }
122 93  
123 94 .ant-tabs-extra-content {
124   - line-height: @multiple-height;
  95 + margin-top: 2px;
  96 + line-height: @multiple-height !important;
  97 +}
  98 +
  99 +.ant-dropdown-trigger {
  100 + display: inline-flex;
125 101 }
126 102  
127 103 .multiple-tabs-content {
... ... @@ -133,7 +109,7 @@
133 109 color: @primary-color;
134 110 text-align: center;
135 111 cursor: pointer;
136   - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  112 + // box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
137 113  
138 114 span[role='img'] {
139 115 transform: rotate(90deg);
... ... @@ -143,8 +119,10 @@
143 119 &__content {
144 120 display: inline-block;
145 121 width: 100%;
146   - padding-left: 10px;
  122 + height: @multiple-height - 2;
  123 + padding-left: 0;
147 124 margin-left: -10px;
  125 + font-size: 12px;
148 126 cursor: pointer;
149 127 user-select: none;
150 128 }
... ...
src/layouts/default/multitabs/index.tsx
... ... @@ -159,7 +159,7 @@ export default defineComponent({
159 159 size="small"
160 160 animated={false}
161 161 hideAdd={true}
162   - tabBarGutter={2}
  162 + tabBarGutter={4}
163 163 activeKey={unref(activeKeyRef)}
164 164 onChange={handleChange}
165 165 onEdit={handleEdit}
... ...
src/layouts/default/setting/index.vue
... ... @@ -28,13 +28,21 @@
28 28  
29 29 .setting-button {
30 30 position: absolute;
  31 + top: 45%;
  32 + right: 0;
31 33 z-index: 10;
32 34 display: flex;
33   - // padding: 10px;
  35 + padding: 10px;
34 36 color: @white;
35 37 cursor: pointer;
36 38 background: @primary-color;
  39 + border-radius: 6px 0 0 6px;
37 40 justify-content: center;
38 41 align-items: center;
  42 +
  43 + svg {
  44 + width: 1em;
  45 + height: 1em;
  46 + }
39 47 }
40 48 </style>
... ...
src/layouts/iframe/index.vue
... ... @@ -9,14 +9,15 @@
9 9 </template>
10 10 <script lang="ts">
11 11 import { defineComponent } from 'vue';
12   - import { useFrameKeepAlive } from './useFrameKeepAlive';
13 12 import FramePage from '/@/views/sys/iframe/index.vue';
  13 +
  14 + import { useFrameKeepAlive } from './useFrameKeepAlive';
  15 +
14 16 export default defineComponent({
15 17 name: 'FrameLayout',
16 18 components: { FramePage },
17 19 setup() {
18   - const { hasRenderFrame, showIframe, getFramePages } = useFrameKeepAlive();
19   - return { hasRenderFrame, showIframe, getFramePages };
  20 + return { ...useFrameKeepAlive() };
20 21 },
21 22 });
22 23 </script>
... ...
src/settings/projectSetting.ts
... ... @@ -55,7 +55,7 @@ const setting: ProjectConfig = {
55 55 // 是否显示搜索框
56 56 showSearch: true,
57 57 // 菜单宽度
58   - menuWidth: 180,
  58 + menuWidth: 200,
59 59 // 菜单模式
60 60 mode: MenuModeEnum.INLINE,
61 61 // 菜单类型
... ... @@ -65,7 +65,7 @@ const setting: ProjectConfig = {
65 65 // 分割菜单
66 66 split: false,
67 67 // 顶部菜单布局
68   - topMenuAlign: 'start',
  68 + topMenuAlign: 'center',
69 69 },
70 70 // 消息配置
71 71 messageSetting: {
... ... @@ -83,7 +83,7 @@ const setting: ProjectConfig = {
83 83 // 开启快速操作
84 84 showQuick: true,
85 85 // 显示icon
86   - showIcon: true,
  86 + showIcon: false,
87 87 // 标签页缓存最大数量
88 88 max: 12,
89 89 },
... ...