From 27e50b47479af8eaeb4be020aeb0fcbdb4308295 Mon Sep 17 00:00:00 2001 From: vben Date: Sun, 13 Dec 2020 22:05:34 +0800 Subject: [PATCH] perf(tabs): perf multiple-tabs --- src/components/Dropdown/index.ts | 4 +- src/components/Menu/src/BasicMenu.tsx | 1 + src/hooks/setting/useMenuSetting.ts | 11 ++ src/layouts/default/LayoutTrigger.tsx | 42 ------ src/layouts/default/content/index.vue | 4 +- src/layouts/default/feature/index.vue | 29 +++++ src/layouts/default/footer/index.less | 28 ---- src/layouts/default/footer/index.tsx | 34 ----- src/layouts/default/footer/index.vue | 74 +++++++++++ src/layouts/default/header/LayoutHeader.tsx | 2 +- .../default/header/LayoutMultipleHeader.tsx | 2 +- src/layouts/default/header/index.less | 3 +- src/layouts/default/index.tsx | 57 ++------ src/layouts/default/index.vue | 95 ++++++++++++++ src/layouts/default/multitabs/TabContent.tsx | 78 ----------- src/layouts/default/multitabs/index.tsx | 114 ---------------- src/layouts/default/setting/index.vue | 2 +- src/layouts/default/sider/useLayoutSider.tsx | 2 +- .../default/tabs/components/QuickButton.vue | 21 +++ .../default/tabs/components/TabContent.vue | 72 ++++++++++ .../default/{multitabs => tabs}/index.less | 90 ++++++++----- src/layouts/default/tabs/index.vue | 123 ++++++++++++++++++ .../default/{multitabs => tabs}/types.ts | 0 .../{multitabs => tabs}/useMultipleTabs.ts | 7 +- .../{multitabs => tabs}/useTabDropdown.ts | 0 src/layouts/default/trigger/HeaderTrigger.vue | 25 ++++ src/layouts/default/trigger/SiderTrigger.vue | 18 +++ src/layouts/default/trigger/index.vue | 21 +++ src/layouts/iframe/index.vue | 16 ++- src/layouts/iframe/useFrameKeepAlive.ts | 6 +- src/layouts/page/index.tsx | 2 + src/layouts/page/useCache.ts | 1 - src/locales/lang/en/layout/multipleTab.ts | 4 +- src/locales/lang/zh_CN/layout/multipleTab.ts | 4 +- src/router/constant.ts | 2 +- 35 files changed, 593 insertions(+), 401 deletions(-) delete mode 100644 src/layouts/default/LayoutTrigger.tsx create mode 100644 src/layouts/default/feature/index.vue delete mode 100644 src/layouts/default/footer/index.less delete mode 100644 src/layouts/default/footer/index.tsx create mode 100644 src/layouts/default/footer/index.vue create mode 100644 src/layouts/default/index.vue delete mode 100644 src/layouts/default/multitabs/TabContent.tsx delete mode 100644 src/layouts/default/multitabs/index.tsx create mode 100644 src/layouts/default/tabs/components/QuickButton.vue create mode 100644 src/layouts/default/tabs/components/TabContent.vue rename src/layouts/default/{multitabs => tabs}/index.less (61%) create mode 100644 src/layouts/default/tabs/index.vue rename src/layouts/default/{multitabs => tabs}/types.ts (100%) rename src/layouts/default/{multitabs => tabs}/useMultipleTabs.ts (91%) rename src/layouts/default/{multitabs => tabs}/useTabDropdown.ts (100%) create mode 100644 src/layouts/default/trigger/HeaderTrigger.vue create mode 100644 src/layouts/default/trigger/SiderTrigger.vue create mode 100644 src/layouts/default/trigger/index.vue diff --git a/src/components/Dropdown/index.ts b/src/components/Dropdown/index.ts index a95b775463c..d229a7f818c 100644 --- a/src/components/Dropdown/index.ts +++ b/src/components/Dropdown/index.ts @@ -1,7 +1,7 @@ import { withInstall } from '../util'; -import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; -export const Dropdown = createAsyncComponent(() => import('./src/Dropdown')); +import Dropdown from './src/Dropdown'; withInstall(Dropdown); export * from './src/types'; +export { Dropdown }; diff --git a/src/components/Menu/src/BasicMenu.tsx b/src/components/Menu/src/BasicMenu.tsx index 91d6cb2aa4e..d33222066a8 100644 --- a/src/components/Menu/src/BasicMenu.tsx +++ b/src/components/Menu/src/BasicMenu.tsx @@ -243,6 +243,7 @@ export default defineComponent({ onOpenChange={handleOpenChange} class={unref(getMenuClass)} onClick={handleMenuClick} + subMenuOpenDelay={0.2} {...unref(getInlineCollapseOptions)} > {{ diff --git a/src/hooks/setting/useMenuSetting.ts b/src/hooks/setting/useMenuSetting.ts index 5b837193ce6..d5fae636884 100644 --- a/src/hooks/setting/useMenuSetting.ts +++ b/src/hooks/setting/useMenuSetting.ts @@ -6,6 +6,7 @@ import { appStore } from '/@/store/modules/app'; import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; +import { useFullContent } from '/@/hooks/web/useFullContent'; // Get menu configuration const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting); @@ -78,6 +79,15 @@ const getCalcContentWidth = computed(() => { return `calc(100% - ${unref(width)}px)`; }); +const { getFullContent: fullContent } = useFullContent(); + +const getShowSidebar = computed(() => { + return ( + unref(getSplit) || + (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent)) + ); +}); + // Set menu configuration function setMenuSetting(menuSetting: Partial): void { appStore.commitProjectConfigState({ menuSetting }); @@ -119,5 +129,6 @@ export function useMenuSetting() { getMenuHidden, getIsTopMenu, getMenuBgColor, + getShowSidebar, }; } diff --git a/src/layouts/default/LayoutTrigger.tsx b/src/layouts/default/LayoutTrigger.tsx deleted file mode 100644 index 3dd8b562967..00000000000 --- a/src/layouts/default/LayoutTrigger.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import type { FunctionalComponent } from 'vue'; - -import { defineComponent, unref } from 'vue'; - -import { - DoubleRightOutlined, - DoubleLeftOutlined, - MenuUnfoldOutlined, - MenuFoldOutlined, -} from '@ant-design/icons-vue'; - -import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; -import { propTypes } from '/@/utils/propTypes'; - -const SiderTrigger: FunctionalComponent = () => { - const { getCollapsed } = useMenuSetting(); - return unref(getCollapsed) ? : ; -}; - -const HeaderTrigger: FunctionalComponent<{ - theme?: string; -}> = (props) => { - const { toggleCollapsed, getCollapsed } = useMenuSetting(); - return ( - - {unref(getCollapsed) ? : } - - ); -}; - -export default defineComponent({ - name: 'LayoutTrigger', - props: { - sider: propTypes.bool.def(true), - theme: propTypes.oneOf(['light', 'dark']), - }, - setup(props) { - return () => { - return props.sider ? : ; - }; - }, -}); diff --git a/src/layouts/default/content/index.vue b/src/layouts/default/content/index.vue index cd2fd768a4d..d3d7d05df6a 100644 --- a/src/layouts/default/content/index.vue +++ b/src/layouts/default/content/index.vue @@ -6,7 +6,7 @@ :loading="getPageLoading" background="rgba(240, 242, 245, 0.6)" absolute - :class="`${prefixCls}__loading`" + :class="`${prefixCls}-loading`" /> @@ -53,7 +53,7 @@ margin: 0 auto; } - &__loading { + &-loading { position: absolute; top: 200px; z-index: @page-loading-z-index; diff --git a/src/layouts/default/feature/index.vue b/src/layouts/default/feature/index.vue new file mode 100644 index 00000000000..50693761fc3 --- /dev/null +++ b/src/layouts/default/feature/index.vue @@ -0,0 +1,29 @@ + + diff --git a/src/layouts/default/footer/index.less b/src/layouts/default/footer/index.less deleted file mode 100644 index 00f6f599b97..00000000000 --- a/src/layouts/default/footer/index.less +++ /dev/null @@ -1,28 +0,0 @@ -@normal-color: rgba(0, 0, 0, 0.45); - -@hover-color: rgba(0, 0, 0, 0.85); - -.layout-footer { - color: @normal-color; - text-align: center; - - &__links { - margin-bottom: 8px; - - a { - color: @normal-color; - - &:hover { - color: @hover-color; - } - } - - .github { - margin: 0 30px; - - &:hover { - color: @hover-color; - } - } - } -} diff --git a/src/layouts/default/footer/index.tsx b/src/layouts/default/footer/index.tsx deleted file mode 100644 index f590742b5d2..00000000000 --- a/src/layouts/default/footer/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import './index.less'; - -import { defineComponent } from 'vue'; -import { Layout } from 'ant-design-vue'; - -import { GithubFilled } from '@ant-design/icons-vue'; - -import { DOC_URL, GITHUB_URL, SITE_URL } from '/@/settings/siteSetting'; -import { openWindow } from '/@/utils'; - -import { useI18n } from '/@/hooks/web/useI18n'; - -export default defineComponent({ - name: 'LayoutContent', - setup() { - const { t } = useI18n(); - return () => { - return ( - - {() => ( - <> - -
Copyright ©2020 Vben Admin
- - )} -
- ); - }; - }, -}); diff --git a/src/layouts/default/footer/index.vue b/src/layouts/default/footer/index.vue new file mode 100644 index 00000000000..c72bad6b490 --- /dev/null +++ b/src/layouts/default/footer/index.vue @@ -0,0 +1,74 @@ + + + + diff --git a/src/layouts/default/header/LayoutHeader.tsx b/src/layouts/default/header/LayoutHeader.tsx index ea218d2b07e..b0fdf2e6441 100644 --- a/src/layouts/default/header/LayoutHeader.tsx +++ b/src/layouts/default/header/LayoutHeader.tsx @@ -19,7 +19,7 @@ import UserDropdown from './UserDropdown'; import LayoutMenu from '../menu'; import LayoutBreadcrumb from './LayoutBreadcrumb.vue'; import LockAction from './actions/LockAction'; -import LayoutTrigger from '../LayoutTrigger'; +import LayoutTrigger from '../trigger/index.vue'; import NoticeAction from './notice/NoticeActionItem.vue'; import { RedoOutlined, diff --git a/src/layouts/default/header/LayoutMultipleHeader.tsx b/src/layouts/default/header/LayoutMultipleHeader.tsx index 6fa7336e117..25bdfc69ab2 100644 --- a/src/layouts/default/header/LayoutMultipleHeader.tsx +++ b/src/layouts/default/header/LayoutMultipleHeader.tsx @@ -3,7 +3,7 @@ import './LayoutMultipleHeader.less'; import { defineComponent, unref, computed, ref, watch, nextTick, CSSProperties } from 'vue'; import LayoutHeader from './LayoutHeader'; -import MultipleTabs from '../multitabs/index'; +import MultipleTabs from '../tabs/index.vue'; import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; diff --git a/src/layouts/default/header/index.less b/src/layouts/default/header/index.less index 76bde3ef407..ac606a9c61a 100644 --- a/src/layouts/default/header/index.less +++ b/src/layouts/default/header/index.less @@ -1,4 +1,5 @@ @import (reference) '../../../design/index.less'; +@header-trigger-prefix-cls: ~'@{namespace}-layout-header-trigger'; .layout-header { display: flex; @@ -24,7 +25,7 @@ height: 100%; align-items: center; - .layout-trigger { + .@{header-trigger-prefix-cls} { display: flex; height: 100%; padding: 1px 10px 0 16px; diff --git a/src/layouts/default/index.tsx b/src/layouts/default/index.tsx index f11dd60cfe5..eca9bc4736a 100644 --- a/src/layouts/default/index.tsx +++ b/src/layouts/default/index.tsx @@ -1,32 +1,28 @@ import './index.less'; -import { defineComponent, unref, computed, ref } from 'vue'; -import { Layout, BackTop } from 'ant-design-vue'; -import LayoutHeader from './header/LayoutHeader'; +import { defineComponent, unref, ref } from 'vue'; +import { Layout } from 'ant-design-vue'; +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; +import LayoutHeader from './header/LayoutHeader'; import LayoutContent from './content/index.vue'; -import LayoutFooter from './footer'; -import LayoutLockPage from '/@/views/sys/lock/index.vue'; import LayoutSideBar from './sider'; -import SettingBtn from './setting/index.vue'; import LayoutMultipleHeader from './header/LayoutMultipleHeader'; -import { MenuModeEnum } from '/@/enums/menuEnum'; - -import { useRouter } from 'vue-router'; -import { useFullContent } from '/@/hooks/web/useFullContent'; import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; -import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { createLayoutContext } from './useLayoutContext'; import { registerGlobComp } from '/@/components/registerGlobComp'; import { createBreakpointListen } from '/@/hooks/event/useBreakpoint'; import { isMobile } from '/@/utils/is'; + +const LayoutFeatures = createAsyncComponent(() => import('/@/layouts/default/feature/index.vue')); +const LayoutFooter = createAsyncComponent(() => import('/@/layouts/default/footer/index.vue')); + export default defineComponent({ name: 'DefaultLayout', setup() { - const { currentRoute } = useRouter(); const headerRef = ref(null); const isMobileRef = ref(false); @@ -43,56 +39,27 @@ export default defineComponent({ const { getShowFullHeaderRef } = useHeaderSetting(); - const { getUseOpenBackTop, getShowSettingButton, getShowFooter } = useRootSetting(); - - const { getShowMenu, getMenuMode, getSplit } = useMenuSetting(); - - const { getFullContent } = useFullContent(); - - const getShowLayoutFooter = computed(() => { - return unref(getShowFooter) && !unref(currentRoute).meta?.hiddenFooter; - }); - - const showSideBarRef = computed(() => { - return ( - unref(getSplit) || - (unref(getShowMenu) && - unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && - !unref(getFullContent)) - ); - }); - - function renderFeatures() { - return ( - <> - - {/* back top */} - {unref(getUseOpenBackTop) && document.body} />} - {/* open setting drawer */} - {unref(getShowSettingButton) && } - - ); - } + const { getShowSidebar } = useMenuSetting(); return () => { return ( {() => ( <> - {renderFeatures()} + {unref(getShowFullHeaderRef) && } {() => ( <> - {unref(showSideBarRef) && } + {unref(getShowSidebar) && } {() => ( <> - {unref(getShowLayoutFooter) && } + )} diff --git a/src/layouts/default/index.vue b/src/layouts/default/index.vue new file mode 100644 index 00000000000..b450e984157 --- /dev/null +++ b/src/layouts/default/index.vue @@ -0,0 +1,95 @@ + + + + diff --git a/src/layouts/default/multitabs/TabContent.tsx b/src/layouts/default/multitabs/TabContent.tsx deleted file mode 100644 index ae5ffcb8a57..00000000000 --- a/src/layouts/default/multitabs/TabContent.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import type { PropType } from 'vue'; -import { Dropdown } from '/@/components/Dropdown/index'; - -import { defineComponent, unref, FunctionalComponent } from 'vue'; - -import { TabContentProps } from './types'; - -import { RightOutlined } from '@ant-design/icons-vue'; - -import { TabContentEnum } from './types'; - -import { useTabDropdown } from './useTabDropdown'; -import { useI18n } from '/@/hooks/web/useI18n'; - -import { RouteLocationNormalized } from 'vue-router'; - -const { t: titleT } = useI18n(); - -const ExtraContent: FunctionalComponent = () => { - return ( - - - - ); -}; - -const TabContent: FunctionalComponent<{ tabItem: RouteLocationNormalized; handler: Fn }> = ( - props -) => { - const { tabItem: { meta } = {} } = props; - - return ( -
- {meta && titleT(meta.title)} -
- ); -}; - -export default defineComponent({ - name: 'TabContent', - props: { - tabItem: { - type: Object as PropType, - default: null, - }, - - type: { - type: Number as PropType, - default: TabContentEnum.TAB_TYPE, - }, - }, - setup(props) { - const { - getDropMenuList, - handleMenuEvent, - handleContextMenu, - getTrigger, - isTabs, - } = useTabDropdown(props as TabContentProps); - - return () => { - return ( - - {() => { - if (!unref(isTabs)) { - return ; - } - return ; - }} - - ); - }; - }, -}); diff --git a/src/layouts/default/multitabs/index.tsx b/src/layouts/default/multitabs/index.tsx deleted file mode 100644 index a92570a9b6d..00000000000 --- a/src/layouts/default/multitabs/index.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import './index.less'; - -import type { TabContentProps } from './types'; - -import { defineComponent, watch, computed, unref, ref } from 'vue'; -import { useRouter } from 'vue-router'; - -import { Tabs } from 'ant-design-vue'; -import TabContent from './TabContent'; - -import { useGo } from '/@/hooks/web/usePage'; - -import { TabContentEnum } from './types'; - -import { tabStore } from '/@/store/modules/tab'; -import { userStore } from '/@/store/modules/user'; - -import { initAffixTabs, useTabsDrag } from './useMultipleTabs'; -import { REDIRECT_NAME } from '/@/router/constant'; - -export default defineComponent({ - name: 'MultipleTabs', - setup() { - const activeKeyRef = ref(''); - - const affixTextList = initAffixTabs(); - - useTabsDrag(affixTextList); - - const go = useGo(); - - const { currentRoute } = useRouter(); - - const getTabsState = computed(() => tabStore.getTabsState); - - watch( - () => tabStore.getLastChangeRouteState?.path, - () => { - if (tabStore.getLastChangeRouteState?.name === REDIRECT_NAME) { - return; - } - const lastChangeRoute = unref(tabStore.getLastChangeRouteState); - if (!lastChangeRoute || !userStore.getTokenState) return; - const { path, fullPath } = lastChangeRoute; - const p = fullPath || path; - if (activeKeyRef.value !== p) { - activeKeyRef.value = p; - } - tabStore.addTabAction(lastChangeRoute); - }, - { - immediate: true, - } - ); - - function handleChange(activeKey: any) { - activeKeyRef.value = activeKey; - go(activeKey, false); - } - - // Close the current tab - function handleEdit(targetKey: string) { - // Added operation to hide, currently only use delete operation - tabStore.closeTabByKeyAction(targetKey); - } - - function renderQuick() { - const tabContentProps: TabContentProps = { - tabItem: currentRoute.value, - type: TabContentEnum.EXTRA_TYPE, - }; - return ; - } - - function renderTabs() { - return unref(getTabsState).map((item) => { - const key = item.query ? item.fullPath : item.path; - const closable = !(item && item.meta && item.meta.affix); - - const slots = { - tab: () => , - }; - return ( - - {slots} - - ); - }); - } - - return () => { - const slots = { - default: () => renderTabs(), - tabBarExtraContent: () => renderQuick(), - }; - return ( -
- - {slots} - -
- ); - }; - }, -}); diff --git a/src/layouts/default/setting/index.vue b/src/layouts/default/setting/index.vue index ec6e5e053ed..da1b1a30e32 100644 --- a/src/layouts/default/setting/index.vue +++ b/src/layouts/default/setting/index.vue @@ -13,7 +13,7 @@ import { useDesign } from '/@/hooks/web/useDesign'; export default defineComponent({ - name: 'SettingBtn', + name: 'SettingButton', components: { SettingOutlined, SettingDrawer }, setup() { const [register, { openDrawer }] = useDrawer(); diff --git a/src/layouts/default/sider/useLayoutSider.tsx b/src/layouts/default/sider/useLayoutSider.tsx index c1e1cc2a9a3..1d8f8410057 100644 --- a/src/layouts/default/sider/useLayoutSider.tsx +++ b/src/layouts/default/sider/useLayoutSider.tsx @@ -1,7 +1,7 @@ import type { Ref } from 'vue'; import { computed, unref, onMounted, nextTick, ref } from 'vue'; -import LayoutTrigger from '/@/layouts/default/LayoutTrigger'; +import LayoutTrigger from '/@/layouts/default/trigger/index.vue'; import { TriggerEnum } from '/@/enums/menuEnum'; diff --git a/src/layouts/default/tabs/components/QuickButton.vue b/src/layouts/default/tabs/components/QuickButton.vue new file mode 100644 index 00000000000..7f2c07e4281 --- /dev/null +++ b/src/layouts/default/tabs/components/QuickButton.vue @@ -0,0 +1,21 @@ + + diff --git a/src/layouts/default/tabs/components/TabContent.vue b/src/layouts/default/tabs/components/TabContent.vue new file mode 100644 index 00000000000..05ca7431b78 --- /dev/null +++ b/src/layouts/default/tabs/components/TabContent.vue @@ -0,0 +1,72 @@ + + diff --git a/src/layouts/default/multitabs/index.less b/src/layouts/default/tabs/index.less similarity index 61% rename from src/layouts/default/multitabs/index.less rename to src/layouts/default/tabs/index.less index 98762990f3e..b4cd9c7c4ca 100644 --- a/src/layouts/default/multitabs/index.less +++ b/src/layouts/default/tabs/index.less @@ -1,10 +1,9 @@ @import (reference) '../../../design/index.less'; +@prefix-cls: ~'@{namespace}-multiple-tabs'; -.multiple-tabs { +.@{prefix-cls} { z-index: 10; height: @multiple-height + 2; - padding: 0 0 2px 0; - margin-left: -1px; line-height: @multiple-height + 2; background: @white; box-shadow: 0 1px 2px 0 rgba(29, 35, 41, 0.05); @@ -32,13 +31,33 @@ line-height: calc(@multiple-height - 2px); color: @text-color-call-out; background: @white; - border: 1px solid darken(@border-color-light, 8%); + border: 1px solid darken(@border-color-light, 6%); transition: none; + &:not(.ant-tabs-tab-active)::before { + position: absolute; + top: -1px; + left: 50%; + width: 100%; + height: 2px; + background-color: @primary-color; + content: ''; + opacity: 0; + transform: translate(-50%, 0) scaleX(0); + transform-origin: center; + transition: none; + } + &:hover { .ant-tabs-close-x { opacity: 1; } + + &:not(.ant-tabs-tab-active)::before { + opacity: 1; + transform: translate(-50%, 0) scaleX(1); + transition: all 0.3s ease-in-out; + } } .ant-tabs-close-x { @@ -51,7 +70,7 @@ &:hover { svg { - width: 0.75em; + width: 0.8em; } } } @@ -73,6 +92,7 @@ color: @white; background: fade(@primary-color, 100%); border: 0; + transition: none; &::before { position: absolute; @@ -98,7 +118,7 @@ } .ant-tabs-nav > div:nth-child(1) { - padding: 0 10px; + padding: 0 6px; .ant-tabs-tab { margin-right: 3px !important; @@ -124,36 +144,42 @@ .ant-dropdown-trigger { display: inline-flex; } -} -.multiple-tabs-content { - &__extra { - display: inline-block; - width: @multiple-height; - height: @multiple-height; - line-height: @multiple-height; - color: #999; - text-align: center; - cursor: pointer; - border-left: 1px solid #eee; - - &:hover { - color: @text-color-base; + &--hide-close { + .ant-tabs-close-x { + opacity: 0 !important; } + } + + &-content { + &__extra { + display: inline-block; + width: @multiple-height; + height: @multiple-height; + line-height: @multiple-height; + color: #999; + text-align: center; + cursor: pointer; + border-left: 1px solid #eee; + + &:hover { + color: @text-color-base; + } - span[role='img'] { - transform: rotate(90deg); + span[role='img'] { + transform: rotate(90deg); + } } - } - &__content { - display: inline-block; - width: 100%; - height: @multiple-height - 2; - padding-left: 0; - margin-left: -10px; - font-size: 12px; - cursor: pointer; - user-select: none; + &__info { + display: inline-block; + width: 100%; + height: @multiple-height - 2; + padding-left: 0; + margin-left: -10px; + font-size: 12px; + cursor: pointer; + user-select: none; + } } } diff --git a/src/layouts/default/tabs/index.vue b/src/layouts/default/tabs/index.vue new file mode 100644 index 00000000000..b027d532960 --- /dev/null +++ b/src/layouts/default/tabs/index.vue @@ -0,0 +1,123 @@ + + + diff --git a/src/layouts/default/multitabs/types.ts b/src/layouts/default/tabs/types.ts similarity index 100% rename from src/layouts/default/multitabs/types.ts rename to src/layouts/default/tabs/types.ts diff --git a/src/layouts/default/multitabs/useMultipleTabs.ts b/src/layouts/default/tabs/useMultipleTabs.ts similarity index 91% rename from src/layouts/default/multitabs/useMultipleTabs.ts rename to src/layouts/default/tabs/useMultipleTabs.ts index b5a7d485eeb..182aad1a7fa 100644 --- a/src/layouts/default/multitabs/useMultipleTabs.ts +++ b/src/layouts/default/tabs/useMultipleTabs.ts @@ -2,6 +2,7 @@ import Sortable from 'sortablejs'; import { toRaw, ref, nextTick, onMounted } from 'vue'; import { RouteLocationNormalized } from 'vue-router'; import { useProjectSetting } from '/@/hooks/setting'; +import { useDesign } from '/@/hooks/web/useDesign'; import router from '/@/router'; import { tabStore } from '/@/store/modules/tab'; import { isNullAndUnDef } from '/@/utils/is'; @@ -48,12 +49,12 @@ export function initAffixTabs(): string[] { export function useTabsDrag(affixTextList: string[]) { const { multiTabsSetting } = useProjectSetting(); + const { prefixCls } = useDesign('multiple-tabs'); + function initSortableTabs() { if (!multiTabsSetting.canDrag) return; nextTick(() => { - const el = document.querySelectorAll( - '.multiple-tabs .ant-tabs-nav > div' - )?.[0] as HTMLElement; + const el = document.querySelectorAll(`.${prefixCls} .ant-tabs-nav > div`)?.[0] as HTMLElement; if (!el) return; Sortable.create(el, { diff --git a/src/layouts/default/multitabs/useTabDropdown.ts b/src/layouts/default/tabs/useTabDropdown.ts similarity index 100% rename from src/layouts/default/multitabs/useTabDropdown.ts rename to src/layouts/default/tabs/useTabDropdown.ts diff --git a/src/layouts/default/trigger/HeaderTrigger.vue b/src/layouts/default/trigger/HeaderTrigger.vue new file mode 100644 index 00000000000..dfafa0575c5 --- /dev/null +++ b/src/layouts/default/trigger/HeaderTrigger.vue @@ -0,0 +1,25 @@ + + diff --git a/src/layouts/default/trigger/SiderTrigger.vue b/src/layouts/default/trigger/SiderTrigger.vue new file mode 100644 index 00000000000..1b6ba655c59 --- /dev/null +++ b/src/layouts/default/trigger/SiderTrigger.vue @@ -0,0 +1,18 @@ + + diff --git a/src/layouts/default/trigger/index.vue b/src/layouts/default/trigger/index.vue new file mode 100644 index 00000000000..0d233a89c09 --- /dev/null +++ b/src/layouts/default/trigger/index.vue @@ -0,0 +1,21 @@ + + diff --git a/src/layouts/iframe/index.vue b/src/layouts/iframe/index.vue index 7f7fe6b58ed..42ccaafecf9 100644 --- a/src/layouts/iframe/index.vue +++ b/src/layouts/iframe/index.vue @@ -1,11 +1,13 @@