Commit 3b126e011c7ca7ac1b008c37aa2cf617242a2e9c
1 parent
899963ba
perf(route): refactor guard
Showing
10 changed files
with
127 additions
and
77 deletions
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 | +} | ... | ... |