Commit f2bdf0b86dd818f3cc59fdb0c55eb1b53b222f7f

Authored by vben
1 parent 949db963

perf: optimize multiple-tab switching effect

src/design/transition/base.less
1 1 .transition-default() {
2 2 &-enter-active,
3 3 &-leave-active {
4   - transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) !important;
  4 + transition: 0.2s cubic-bezier(0.25, 0.8, 0.5, 1) !important;
5 5 }
6 6  
7 7 &-move {
8   - transition: transform 0.6s;
  8 + transition: transform 0.5s;
9 9 }
10 10 }
11 11  
... ...
src/design/transition/breadcrumb.less
1 1 .breadcrumb-enter-active,
2 2 .breadcrumb-leave-active {
3   - transition: all 0.38s;
  3 + transition: all 0.24s;
4 4 }
5 5  
6 6 .breadcrumb-enter-from,
... ...
src/design/transition/fade.less
1 1 .fade-enter-active,
2 2 .fade-leave-active {
3   - transition: opacity 0.28s ease-in-out;
  3 + transition: opacity 0.2s ease-in-out;
4 4 }
5 5  
6 6 .fade-enter-from,
... ... @@ -11,7 +11,7 @@
11 11 // side-fade
12 12 .slide-fade-enter-active,
13 13 .slide-fade-leave-active {
14   - transition: opacity 0.35s, transform 0.4s;
  14 + transition: opacity 0.3s, transform 0.35s;
15 15 }
16 16  
17 17 .slide-enter-from,
... ... @@ -32,7 +32,7 @@
32 32 // Speed: 1x
33 33 .fade-bottom-enter-active,
34 34 .fade-bottom-leave-active {
35   - transition: opacity 0.3s, transform 0.35s;
  35 + transition: opacity 0.2s, transform 0.25s;
36 36 }
37 37  
38 38 .fade-bottom-enter-from,
... ... @@ -53,7 +53,7 @@
53 53 // Speed: 1x
54 54 .fade-top-enter-active,
55 55 .fade-top-leave-active {
56   - transition: opacity 0.3s, transform 0.35s;
  56 + transition: opacity 0.2s, transform 0.25s;
57 57 }
58 58  
59 59 .fade-top-enter-from {
... ...
src/design/transition/zoom.less
1 1 // zoom-out
2 2 .zoom-out-enter-active,
3 3 .zoom-out-leave-active {
4   - transition: opacity 0.35s ease-in-out, transform 0.45s ease-out;
  4 + transition: opacity 0.2 ease-in-out, transform 0.2s ease-out;
5 5 }
6 6  
7 7 .zoom-out-enter-from,
... ... @@ -13,7 +13,7 @@
13 13 // zoom-fade
14 14 .zoom-fade-enter-active,
15 15 .zoom-fade-leave-active {
16   - transition: transform 0.35s, opacity 0.35s ease-out;
  16 + transition: transform 0.2s, opacity 0.2s ease-out;
17 17 }
18 18  
19 19 .zoom-fade-enter-from {
... ...
src/hooks/web/useTabs.ts
  1 +import { useTimeout } from '/@/hooks/core/useTimeout';
  2 +import { PageEnum } from '/@/enums/pageEnum';
1 3 import { TabItem, tabStore } from '/@/store/modules/tab';
2 4 import { appStore } from '/@/store/modules/app';
  5 +import router from '/@/router';
  6 +
3 7 type Fn = () => void;
4 8 type RouteFn = (tabItem: TabItem) => void;
5 9  
... ... @@ -66,5 +70,12 @@ export function useTabs() {
66 70 closeOther: () => canIUseFn() && closeOther(tabStore.getCurrentTab),
67 71 closeCurrent: () => canIUseFn() && closeCurrent(tabStore.getCurrentTab),
68 72 resetCache: () => canIUseFn() && resetCache(),
  73 + addTab: (path: PageEnum, goTo = false) => {
  74 + useTimeout(() => {
  75 + tabStore.addTabByPathAction(path);
  76 + }, 0);
  77 +
  78 + goTo && router.push(path);
  79 + },
69 80 };
70 81 }
... ...
src/layouts/default/LayoutMenu.tsx
... ... @@ -5,7 +5,6 @@ import { computed, defineComponent, unref, ref, onMounted, watch } from 'vue';
5 5 import { BasicMenu } from '/@/components/Menu/index';
6 6 import Logo from '/@/layouts/Logo.vue';
7 7  
8   -import { PageEnum } from '/@/enums/pageEnum';
9 8 import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
10 9  
11 10 // store
... ... @@ -20,10 +19,11 @@ import {
20 19 getFlatChildrenMenus,
21 20 getCurrentParentPath,
22 21 } from '/@/router/menus/index';
23   -import { useGo } from '/@/hooks/web/usePage';
24 22 import { useRouter } from 'vue-router';
25 23 import { useThrottle } from '/@/hooks/core/useThrottle';
26 24 import { permissionStore } from '/@/store/modules/permission';
  25 +import { useTabs } from '/@/hooks/web/useTabs';
  26 +import { PageEnum } from '/@/enums/pageEnum';
27 27  
28 28 // import
29 29 export default defineComponent({
... ... @@ -54,6 +54,7 @@ export default defineComponent({
54 54 const menusRef = ref<Menu[]>([]);
55 55 const flatMenusRef = ref<Menu[]>([]);
56 56 const { currentRoute } = useRouter();
  57 + const { addTab } = useTabs();
57 58  
58 59 const getProjectConfigRef = computed(() => {
59 60 return appStore.getProjectConfig;
... ... @@ -63,7 +64,6 @@ export default defineComponent({
63 64 return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
64 65 });
65 66  
66   - const go = useGo();
67 67 onMounted(() => {
68 68 genMenus();
69 69 });
... ... @@ -144,7 +144,7 @@ export default defineComponent({
144 144 if (splitType === MenuSplitTyeEnum.TOP) {
145 145 menuStore.commitCurrentTopSplitMenuPathState(path);
146 146 }
147   - go(path as PageEnum);
  147 + addTab(path as PageEnum, true);
148 148 }
149 149 }
150 150  
... ...
src/layouts/default/multitabs/index.tsx
... ... @@ -2,7 +2,7 @@ import type { TabContentProps } from &#39;./tab.data&#39;;
2 2 import type { TabItem } from '/@/store/modules/tab';
3 3 import type { AppRouteRecordRaw } from '/@/router/types';
4 4  
5   -import { defineComponent, watch, computed, ref, unref } from 'vue';
  5 +import { defineComponent, watch, computed, ref, unref, onMounted } from 'vue';
6 6 import { Tabs } from 'ant-design-vue';
7 7 import TabContent from './TabContent';
8 8  
... ... @@ -16,12 +16,21 @@ import &#39;./index.less&#39;;
16 16 import { tabStore } from '/@/store/modules/tab';
17 17 import { closeTab } from './useTabDropdown';
18 18 import router from '/@/router';
  19 +import { useTabs } from '/@/hooks/web/useTabs';
  20 +import { PageEnum } from '/@/enums/pageEnum';
  21 +
19 22 export default defineComponent({
20 23 name: 'MultiTabs',
21 24 setup() {
22 25 let isAddAffix = false;
23 26 const go = useGo();
24 27 const { currentRoute } = useRouter();
  28 +
  29 + onMounted(() => {
  30 + const { addTab } = useTabs();
  31 + addTab(unref(currentRoute).path as PageEnum);
  32 + });
  33 +
25 34 // 当前激活tab
26 35 const activeKeyRef = ref<string>('');
27 36 // 当前tab列表
... ... @@ -38,7 +47,9 @@ export default defineComponent({
38 47 }
39 48 activeKeyRef.value = path;
40 49  
41   - tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw);
  50 + // 监听路由的话虽然可以,但是路由切换的时间会造成卡顿现象?
  51 + // 使用useTab的addTab的话,当用户手动调转,需要自行调用addTab
  52 + // tabStore.commitAddTab((unref(currentRoute) as unknown) as AppRouteRecordRaw);
42 53 },
43 54 {
44 55 immediate: true,
... ...
src/router/guard/pageLoadingGuard.ts
... ... @@ -6,6 +6,9 @@ import { userStore } from &#39;/@/store/modules/user&#39;;
6 6 export function createPageLoadingGuard(router: Router) {
7 7 let isFirstLoad = true;
8 8 router.beforeEach(async (to) => {
  9 + console.log('======================');
  10 + console.log(2);
  11 + console.log('======================');
9 12 const {
10 13 openKeepAlive,
11 14 openRouterTransition,
... ... @@ -21,6 +24,7 @@ export function createPageLoadingGuard(router: Router) {
21 24 }
22 25 if (show && openKeepAlive && !isFirstLoad) {
23 26 const tabList = tabStore.getTabsState;
  27 +
24 28 const isOpen = tabList.some((tab) => tab.path === to.path);
25 29 appStore.setPageLoadingAction(!isOpen);
26 30 } else {
... ...
src/store/modules/tab.ts
... ... @@ -181,6 +181,14 @@ class Tab extends VuexModule {
181 181 }
182 182  
183 183 @Action
  184 + addTabByPathAction(path: string): void {
  185 + if (!path) return;
  186 + const routes = router.getRoutes();
  187 + const to = routes.find((item) => item.path === path);
  188 + to && this.commitAddTab((to as unknown) as AppRouteRecordRaw);
  189 + }
  190 +
  191 + @Action
184 192 closeRightTabAction(route: AppRouteRecordRaw | TabItem): void {
185 193 const index = this.tabsState.findIndex((item) => item.path === route.path);
186 194  
... ...
src/views/demo/feat/tabs/index.vue
... ... @@ -11,19 +11,40 @@
11 11 <a-button class="mr-2" @click="closeOther">关闭其他</a-button>
12 12 <a-button class="mr-2" @click="closeCurrent">关闭当前</a-button>
13 13 <a-button class="mr-2" @click="refreshPage">刷新当前</a-button>
  14 + <a-button class="mr-2" @click="openTab">打开图标界面tab</a-button>
14 15 </CollapseContainer>
15 16 </div>
16 17 </template>
17 18 <script lang="ts">
18 19 import { defineComponent } from 'vue';
19 20 import { CollapseContainer } from '/@/components/Container/index';
  21 + import { PageEnum } from '/@/enums/pageEnum';
20 22 import { useTabs } from '/@/hooks/web/useTabs';
21 23 export default defineComponent({
22 24 name: 'TabsDemo',
23 25 components: { CollapseContainer },
24 26 setup() {
25   - const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTabs();
26   - return { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage };
  27 + const {
  28 + closeAll,
  29 + closeLeft,
  30 + closeRight,
  31 + closeOther,
  32 + closeCurrent,
  33 + refreshPage,
  34 + addTab,
  35 + } = useTabs();
  36 +
  37 + return {
  38 + closeAll,
  39 + closeLeft,
  40 + closeRight,
  41 + closeOther,
  42 + closeCurrent,
  43 + refreshPage,
  44 + openTab: () => {
  45 + addTab('/feat/icon' as PageEnum, true);
  46 + },
  47 + };
27 48 },
28 49 });
29 50 </script>
... ...