Explorar o código

perf: layout style optimization

vben %!s(int64=4) %!d(string=hai) anos
pai
achega
7702832181

+ 1 - 1
.env

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

+ 10 - 0
CHANGELOG.zh_CN.md

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

BIN=BIN
src/assets/images/logo.png


+ 1 - 1
src/components/Breadcrumb/Breadcrumb.vue

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

+ 2 - 2
src/components/Menu/src/BasicMenu.tsx

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

+ 1 - 1
src/components/Menu/src/SearchInput.vue

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

+ 12 - 20
src/components/Menu/src/index.less

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

+ 4 - 0
src/components/Menu/src/props.ts

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

+ 5 - 0
src/design/ant/index.less

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

+ 3 - 2
src/design/index.less

@@ -36,7 +36,8 @@ input::-ms-reveal {
 }
 
 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-weight: normal;
   line-height: 1.428571429; // 20/14
@@ -149,7 +150,7 @@ object {
 }
 
 .ant-layout {
-  background: #f1f1f6;
+  background: #f0f2f5;
 
   &-content {
     position: relative;

+ 5 - 5
src/design/public.less

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

+ 4 - 4
src/design/var/index.less

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

+ 25 - 6
src/layouts/Logo.vue

@@ -1,18 +1,23 @@
 <template>
-  <div class="app-logo" @click="handleGoHome">
+  <div class="app-logo" @click="handleGoHome" :style="wrapStyle">
     <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>
 </template>
 <script lang="ts">
-  import { defineComponent, PropType, ref, watch } from 'vue';
+  import { computed, defineComponent, PropType, ref, watch } from 'vue';
   // hooks
   import { useSetting } from '/@/hooks/core/useSetting';
+  import { useTimeout } from '/@/hooks/core/useTimeout';
+  import { useGo } from '/@/hooks/web/usePage';
 
   import { PageEnum } from '/@/enums/pageEnum';
+  import { MenuTypeEnum } from '../enums/menuEnum';
+
   import logo from '/@/assets/images/logo.png';
-  import { useTimeout } from '/@/hooks/core/useTimeout';
-  import { useGo } from '/@/hooks/web/usePage';
+
+  import { menuStore } from '../store/modules/menu';
+  import { appStore } from '../store/modules/app';
 
   export default defineComponent({
     name: 'Logo',
@@ -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 {
         handleGoHome,
         globSetting,
         show: showRef,
         logo,
+        wrapStyle,
       };
     },
   });
@@ -59,12 +77,13 @@
   .app-logo {
     display: flex;
     align-items: center;
+    padding-left: 16px;
     cursor: pointer;
 
     .logo-title {
       display: none;
-      font-family: Georgia, serif;
       font-size: 16px;
+      font-weight: 400;
       .respond-to(medium,{
        display: block;
      });

+ 1 - 4
src/layouts/default/LayoutContent.tsx

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

+ 20 - 9
src/layouts/default/LayoutHeader.tsx

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

+ 5 - 0
src/layouts/default/LayoutMenu.tsx

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

+ 6 - 5
src/layouts/default/LayoutSideBar.tsx

@@ -7,7 +7,7 @@ import { menuStore } from '/@/store/modules/menu';
 // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
 // import lightMiniImg from '/@/assets/images/sidebar/light-mini.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 { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
 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 theme = unref(getProjectConfigRef).menuSetting.theme;
+      if (theme === MenuThemeEnum.LIGHT) {
+        // bg = lightImg;
+        return {};
+      }
       let bg = '';
       if (theme === MenuThemeEnum.DARK) {
         // bg = collapse ? darkMiniIMg : darkImg;
         bg = darkImg;
       }
-      if (theme === MenuThemeEnum.LIGHT) {
-        bg = lightImg;
-        // bg = collapse ? lightMiniImg : lightImg;
-      }
+
       return {
         'background-image': `url(${bg})`,
       };

+ 25 - 25
src/layouts/default/UserDropdown.tsx

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

+ 2 - 2
src/layouts/default/actions/LockActionItem.less

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

+ 1 - 1
src/layouts/default/actions/LockActionItem.tsx

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

+ 17 - 64
src/layouts/default/index.less

@@ -1,12 +1,6 @@
 @import (reference) '../../design/index.less';
 
 .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 {
     position: relative;
 
@@ -72,6 +66,10 @@
   .layout-sidebar {
     background-size: 100% 100%;
 
+    &:not(.ant-layout-sider-dark) {
+      border-right: 1px solid @border-color-light;
+    }
+
     .ant-layout-sider-zero-width-trigger {
       top: 40%;
       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 {
     z-index: 10;
     height: @multiple-height;
     padding: 0;
     line-height: @multiple-height;
     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;
   line-height: @header-height;
 }
 
+.ant-layout-header.default-layout__tabs {
+  height: @multiple-height + 2;
+  line-height: @multiple-height + 2;
+  background: @white;
+}
+
 .layout-header {
   display: flex;
   height: @header-height;
@@ -351,22 +343,20 @@
   }
 
   &__menu {
-    // display: flex;
     margin-left: 20px;
     overflow: hidden;
     align-items: center;
-    // flex-grow: 1;
   }
 
   &__user-dropdown {
-    height: 52px;
+    height: @header-height;
     padding: 0 0 0 10px;
   }
 }
 
 .user-dropdown {
   display: flex;
-  height: 100%;
+  padding-right: 10px;
   font-size: 12px;
   cursor: pointer;
   align-items: center;
@@ -374,49 +364,12 @@
   img {
     width: 26px;
     height: 26px;
-    margin-right: 16px;
+    margin-right: 12px;
   }
 
   &__header {
     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 {
@@ -425,8 +378,8 @@
 }
 
 .ant-layout-sider-trigger {
-  height: 30px;
-  line-height: 30px;
+  height: 36px;
+  line-height: 36px;
 }
 
 .hide-title {

+ 6 - 8
src/layouts/default/index.tsx

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

+ 27 - 49
src/layouts/default/multitabs/index.less

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

+ 1 - 1
src/layouts/default/multitabs/index.tsx

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

+ 9 - 1
src/layouts/default/setting/index.vue

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

+ 4 - 3
src/layouts/iframe/index.vue

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

+ 3 - 3
src/settings/projectSetting.ts

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