Commit 3b126e011c7ca7ac1b008c37aa2cf617242a2e9c

Authored by vben
1 parent 899963ba

perf(route): refactor guard

src/components/Modal/src/BasicModal.vue
... ... @@ -16,6 +16,7 @@
16 16 <template #footer v-if="!$slots.footer">
17 17 <ModalFooter v-bind="getProps" @ok="handleOk" @cancel="handleCancel" />
18 18 </template>
  19 +
19 20 <ModalWrapper
20 21 :useWrapper="getProps.useWrapper"
21 22 :footerOffset="wrapperFooterOffset"
... ... @@ -30,6 +31,10 @@
30 31 >
31 32 <slot />
32 33 </ModalWrapper>
  34 +
  35 + <template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
  36 + <slot :name="item" v-bind="data" />
  37 + </template>
33 38 </Modal>
34 39 </template>
35 40 <script lang="ts">
... ...
src/components/Modal/src/components/ModalWrapper.vue
... ... @@ -48,6 +48,7 @@
48 48 const wrapperRef = ref<ComponentRef>(null);
49 49 const spinRef = ref<ElRef>(null);
50 50 const realHeightRef = ref(0);
  51 + const minRealHeightRef = ref(0);
51 52  
52 53 let stopElResizeFn: Fn = () => {};
53 54  
... ... @@ -82,10 +83,13 @@
82 83  
83 84 watch(
84 85 () => props.fullScreen,
85   - () => {
86   - setTimeout(() => {
87   - setModalHeight();
88   - }, 0);
  86 + (v) => {
  87 + setModalHeight();
  88 + if (!v) {
  89 + realHeightRef.value = minRealHeightRef.value;
  90 + } else {
  91 + minRealHeightRef.value = realHeightRef.value;
  92 + }
89 93 }
90 94 );
91 95  
... ...
src/components/Modal/src/hooks/useModalFullScreen.ts
... ... @@ -7,7 +7,7 @@ export interface UseFullScreenContext {
7 7 }
8 8  
9 9 export function useFullScreen(context: UseFullScreenContext) {
10   - const formerHeightRef = ref(0);
  10 + // const formerHeightRef = ref(0);
11 11 const fullScreenRef = ref(false);
12 12  
13 13 const getWrapClassName = computed(() => {
... ... @@ -20,25 +20,25 @@ export function useFullScreen(context: UseFullScreenContext) {
20 20 e && e.stopPropagation();
21 21 fullScreenRef.value = !unref(fullScreenRef);
22 22  
23   - const modalWrapper = unref(context.modalWrapperRef);
  23 + // const modalWrapper = unref(context.modalWrapperRef);
24 24  
25   - if (!modalWrapper) return;
  25 + // if (!modalWrapper) return;
26 26  
27   - const wrapperEl = modalWrapper.$el as HTMLElement;
28   - if (!wrapperEl) return;
29   - const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement;
  27 + // const wrapperEl = modalWrapper.$el as HTMLElement;
  28 + // if (!wrapperEl) return;
  29 + // const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement;
30 30  
31   - if (!modalWrapSpinEl) return;
  31 + // if (!modalWrapSpinEl) return;
32 32  
33   - if (!unref(formerHeightRef) && unref(fullScreenRef)) {
34   - formerHeightRef.value = modalWrapSpinEl.offsetHeight;
35   - }
  33 + // if (!unref(formerHeightRef) && unref(fullScreenRef)) {
  34 + // formerHeightRef.value = modalWrapSpinEl.offsetHeight;
  35 + // }
36 36  
37   - if (unref(fullScreenRef)) {
38   - modalWrapSpinEl.style.height = `${window.innerHeight - unref(context.extHeightRef)}px`;
39   - } else {
40   - modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`;
41   - }
  37 + // if (unref(fullScreenRef)) {
  38 + // modalWrapSpinEl.style.height = `${window.innerHeight - unref(context.extHeightRef)}px`;
  39 + // } else {
  40 + // modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`;
  41 + // }
42 42 }
43 43 return { getWrapClassName, handleFullScreen, fullScreenRef };
44 44 }
... ...
src/router/guard/httpGuard.ts 0 → 100644
  1 +import type { Router } from 'vue-router';
  2 +import { useProjectSetting } from '/@/hooks/setting';
  3 +import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
  4 +
  5 +export function createHttpGuard(router: Router) {
  6 + const { removeAllHttpPending } = useProjectSetting();
  7 + let axiosCanceler: Nullable<AxiosCanceler>;
  8 + if (removeAllHttpPending) {
  9 + axiosCanceler = new AxiosCanceler();
  10 + }
  11 + router.beforeEach(async () => {
  12 + // Switching the route will delete the previous request
  13 + removeAllHttpPending && axiosCanceler?.removeAllPending();
  14 + return true;
  15 + });
  16 +}
... ...
src/router/guard/index.ts
1   -import { RouteLocationNormalized, Router } from 'vue-router';
2   -
3   -import { Modal, notification } from 'ant-design-vue';
  1 +import { Router } from 'vue-router';
4 2  
5 3 import { createProgressGuard } from './progressGuard';
6 4 import { createPermissionGuard } from './permissionGuard';
7 5 import { createPageLoadingGuard } from './pageLoadingGuard';
8   -
9   -import { useGlobSetting, useProjectSetting } from '/@/hooks/setting';
10   -
11   -import { setTitle } from '/@/utils/browser';
12   -import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
13   -
14   -import { useI18n } from '/@/hooks/web/useI18n';
15   -import { REDIRECT_NAME } from '/@/router/constant';
16   -import { setLastChangeTab } from '/@/logics/mitt/tabChange';
17   -
18   -const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting();
19   -const globSetting = useGlobSetting();
20   -
21   -const body = document.body;
22   -
23   -const isHash = (href: string) => {
24   - return /^#/.test(href);
25   -};
  6 +import { createTitleGuard } from './titleGuard';
  7 +import { createMessageGuard } from './messageGuard';
  8 +import { createScrollGuard } from './scrollGuard';
  9 +import { createHttpGuard } from './httpGuard';
  10 +import { createPageGuard } from './pageGuard';
26 11  
27 12 export function createGuard(router: Router) {
28   - let axiosCanceler: Nullable<AxiosCanceler>;
29   - if (removeAllHttpPending) {
30   - axiosCanceler = new AxiosCanceler();
31   - }
32   - const loadedPageMap = new Map<string, boolean>();
33   -
34   - router.beforeEach(async (to) => {
35   - to.meta.loaded = !!loadedPageMap.get(to.path);
36   - // Notify routing changes
37   - setLastChangeTab(to);
38   - try {
39   - if (closeMessageOnSwitch) {
40   - Modal.destroyAll();
41   - notification.destroy();
42   - }
43   - // Switching the route will delete the previous request
44   - removeAllHttpPending && axiosCanceler!.removeAllPending();
45   - } catch (error) {
46   - console.warn('basic guard error:' + error);
47   - }
48   - return true;
49   - });
50   -
51   - router.afterEach((to) => {
52   - // scroll top
53   - isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
54   -
55   - loadedPageMap.set(to.path, true);
56   -
57   - const { t } = useI18n();
58   -
59   - // change html title
60   - to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title);
61   - });
  13 + createPageGuard(router);
  14 + createHttpGuard(router);
  15 + createScrollGuard(router);
  16 + createMessageGuard(router);
  17 + createTitleGuard(router);
62 18 createPageLoadingGuard(router);
63 19 createProgressGuard(router);
64 20 createPermissionGuard(router);
... ...
src/router/guard/messageGuard.ts 0 → 100644
  1 +import type { Router } from 'vue-router';
  2 +import { useProjectSetting } from '/@/hooks/setting';
  3 +import { Modal, notification } from 'ant-design-vue';
  4 +
  5 +import { warn } from '/@/utils/log';
  6 +
  7 +export function createMessageGuard(router: Router) {
  8 + const { closeMessageOnSwitch } = useProjectSetting();
  9 +
  10 + router.beforeEach(async () => {
  11 + try {
  12 + if (closeMessageOnSwitch) {
  13 + Modal.destroyAll();
  14 + notification.destroy();
  15 + }
  16 + } catch (error) {
  17 + warn('message guard error:' + error);
  18 + }
  19 + return true;
  20 + });
  21 +}
... ...
src/router/guard/pageGuard.ts 0 → 100644
  1 +import type { Router } from 'vue-router';
  2 +import { setLastChangeTab } from '/@/logics/mitt/tabChange';
  3 +
  4 +export function createPageGuard(router: Router) {
  5 + const loadedPageMap = new Map<string, boolean>();
  6 +
  7 + router.beforeEach(async (to) => {
  8 + to.meta.loaded = !!loadedPageMap.get(to.path);
  9 + // Notify routing changes
  10 + setLastChangeTab(to);
  11 +
  12 + return true;
  13 + });
  14 +
  15 + router.afterEach((to) => {
  16 + loadedPageMap.set(to.path, true);
  17 + });
  18 +}
... ...
src/router/guard/scrollGuard.ts 0 → 100644
  1 +import type { RouteLocationNormalized, Router } from 'vue-router';
  2 +
  3 +const isHash = (href: string) => {
  4 + return /^#/.test(href);
  5 +};
  6 +
  7 +export function createScrollGuard(router: Router) {
  8 + const body = document.body;
  9 +
  10 + router.afterEach(async (to) => {
  11 + // scroll top
  12 + isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
  13 + return true;
  14 + });
  15 +}
... ...
src/router/guard/titleGuard.ts 0 → 100644
  1 +import type { Router } from 'vue-router';
  2 +
  3 +import { useGlobSetting } from '/@/hooks/setting';
  4 +
  5 +import { setTitle } from '/@/utils/browser';
  6 +import { useI18n } from '/@/hooks/web/useI18n';
  7 +
  8 +import { REDIRECT_NAME } from '/@/router/constant';
  9 +
  10 +const globSetting = useGlobSetting();
  11 +
  12 +export function createTitleGuard(router: Router) {
  13 + router.afterEach(async (to) => {
  14 + const { t } = useI18n();
  15 + to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title);
  16 + return true;
  17 + });
  18 +}
... ...
src/views/demo/comp/modal/Modal1.vue
... ... @@ -8,8 +8,5 @@
8 8 import { BasicModal } from '/@/components/Modal';
9 9 export default defineComponent({
10 10 components: { BasicModal },
11   - setup() {
12   - return {};
13   - },
14 11 });
15 12 </script>
... ...