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,6 +16,7 @@ | ||
16 | <template #footer v-if="!$slots.footer"> | 16 | <template #footer v-if="!$slots.footer"> |
17 | <ModalFooter v-bind="getProps" @ok="handleOk" @cancel="handleCancel" /> | 17 | <ModalFooter v-bind="getProps" @ok="handleOk" @cancel="handleCancel" /> |
18 | </template> | 18 | </template> |
19 | + | ||
19 | <ModalWrapper | 20 | <ModalWrapper |
20 | :useWrapper="getProps.useWrapper" | 21 | :useWrapper="getProps.useWrapper" |
21 | :footerOffset="wrapperFooterOffset" | 22 | :footerOffset="wrapperFooterOffset" |
@@ -30,6 +31,10 @@ | @@ -30,6 +31,10 @@ | ||
30 | > | 31 | > |
31 | <slot /> | 32 | <slot /> |
32 | </ModalWrapper> | 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 | </Modal> | 38 | </Modal> |
34 | </template> | 39 | </template> |
35 | <script lang="ts"> | 40 | <script lang="ts"> |
src/components/Modal/src/components/ModalWrapper.vue
@@ -48,6 +48,7 @@ | @@ -48,6 +48,7 @@ | ||
48 | const wrapperRef = ref<ComponentRef>(null); | 48 | const wrapperRef = ref<ComponentRef>(null); |
49 | const spinRef = ref<ElRef>(null); | 49 | const spinRef = ref<ElRef>(null); |
50 | const realHeightRef = ref(0); | 50 | const realHeightRef = ref(0); |
51 | + const minRealHeightRef = ref(0); | ||
51 | 52 | ||
52 | let stopElResizeFn: Fn = () => {}; | 53 | let stopElResizeFn: Fn = () => {}; |
53 | 54 | ||
@@ -82,10 +83,13 @@ | @@ -82,10 +83,13 @@ | ||
82 | 83 | ||
83 | watch( | 84 | watch( |
84 | () => props.fullScreen, | 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 +7,7 @@ export interface UseFullScreenContext { | ||
7 | } | 7 | } |
8 | 8 | ||
9 | export function useFullScreen(context: UseFullScreenContext) { | 9 | export function useFullScreen(context: UseFullScreenContext) { |
10 | - const formerHeightRef = ref(0); | 10 | + // const formerHeightRef = ref(0); |
11 | const fullScreenRef = ref(false); | 11 | const fullScreenRef = ref(false); |
12 | 12 | ||
13 | const getWrapClassName = computed(() => { | 13 | const getWrapClassName = computed(() => { |
@@ -20,25 +20,25 @@ export function useFullScreen(context: UseFullScreenContext) { | @@ -20,25 +20,25 @@ export function useFullScreen(context: UseFullScreenContext) { | ||
20 | e && e.stopPropagation(); | 20 | e && e.stopPropagation(); |
21 | fullScreenRef.value = !unref(fullScreenRef); | 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 | return { getWrapClassName, handleFullScreen, fullScreenRef }; | 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 | import { createProgressGuard } from './progressGuard'; | 3 | import { createProgressGuard } from './progressGuard'; |
6 | import { createPermissionGuard } from './permissionGuard'; | 4 | import { createPermissionGuard } from './permissionGuard'; |
7 | import { createPageLoadingGuard } from './pageLoadingGuard'; | 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 | export function createGuard(router: Router) { | 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 | createPageLoadingGuard(router); | 18 | createPageLoadingGuard(router); |
63 | createProgressGuard(router); | 19 | createProgressGuard(router); |
64 | createPermissionGuard(router); | 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 +8,5 @@ | ||
8 | import { BasicModal } from '/@/components/Modal'; | 8 | import { BasicModal } from '/@/components/Modal'; |
9 | export default defineComponent({ | 9 | export default defineComponent({ |
10 | components: { BasicModal }, | 10 | components: { BasicModal }, |
11 | - setup() { | ||
12 | - return {}; | ||
13 | - }, | ||
14 | }); | 11 | }); |
15 | </script> | 12 | </script> |