Commit 3b126e011c7ca7ac1b008c37aa2cf617242a2e9c

Authored by vben
1 parent 899963ba

perf(route): refactor guard

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>