mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 16:46:19 +08:00
perf(route): refactor guard
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
<template #footer v-if="!$slots.footer">
|
<template #footer v-if="!$slots.footer">
|
||||||
<ModalFooter v-bind="getProps" @ok="handleOk" @cancel="handleCancel" />
|
<ModalFooter v-bind="getProps" @ok="handleOk" @cancel="handleCancel" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<ModalWrapper
|
<ModalWrapper
|
||||||
:useWrapper="getProps.useWrapper"
|
:useWrapper="getProps.useWrapper"
|
||||||
:footerOffset="wrapperFooterOffset"
|
:footerOffset="wrapperFooterOffset"
|
||||||
@@ -30,6 +31,10 @@
|
|||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
|
|
||||||
|
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
||||||
|
<slot :name="item" v-bind="data" />
|
||||||
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
const wrapperRef = ref<ComponentRef>(null);
|
const wrapperRef = ref<ComponentRef>(null);
|
||||||
const spinRef = ref<ElRef>(null);
|
const spinRef = ref<ElRef>(null);
|
||||||
const realHeightRef = ref(0);
|
const realHeightRef = ref(0);
|
||||||
|
const minRealHeightRef = ref(0);
|
||||||
|
|
||||||
let stopElResizeFn: Fn = () => {};
|
let stopElResizeFn: Fn = () => {};
|
||||||
|
|
||||||
@@ -82,10 +83,13 @@
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.fullScreen,
|
() => props.fullScreen,
|
||||||
() => {
|
(v) => {
|
||||||
setTimeout(() => {
|
setModalHeight();
|
||||||
setModalHeight();
|
if (!v) {
|
||||||
}, 0);
|
realHeightRef.value = minRealHeightRef.value;
|
||||||
|
} else {
|
||||||
|
minRealHeightRef.value = realHeightRef.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ export interface UseFullScreenContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useFullScreen(context: UseFullScreenContext) {
|
export function useFullScreen(context: UseFullScreenContext) {
|
||||||
const formerHeightRef = ref(0);
|
// const formerHeightRef = ref(0);
|
||||||
const fullScreenRef = ref(false);
|
const fullScreenRef = ref(false);
|
||||||
|
|
||||||
const getWrapClassName = computed(() => {
|
const getWrapClassName = computed(() => {
|
||||||
@@ -20,25 +20,25 @@ export function useFullScreen(context: UseFullScreenContext) {
|
|||||||
e && e.stopPropagation();
|
e && e.stopPropagation();
|
||||||
fullScreenRef.value = !unref(fullScreenRef);
|
fullScreenRef.value = !unref(fullScreenRef);
|
||||||
|
|
||||||
const modalWrapper = unref(context.modalWrapperRef);
|
// const modalWrapper = unref(context.modalWrapperRef);
|
||||||
|
|
||||||
if (!modalWrapper) return;
|
// if (!modalWrapper) return;
|
||||||
|
|
||||||
const wrapperEl = modalWrapper.$el as HTMLElement;
|
// const wrapperEl = modalWrapper.$el as HTMLElement;
|
||||||
if (!wrapperEl) return;
|
// if (!wrapperEl) return;
|
||||||
const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement;
|
// const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement;
|
||||||
|
|
||||||
if (!modalWrapSpinEl) return;
|
// if (!modalWrapSpinEl) return;
|
||||||
|
|
||||||
if (!unref(formerHeightRef) && unref(fullScreenRef)) {
|
// if (!unref(formerHeightRef) && unref(fullScreenRef)) {
|
||||||
formerHeightRef.value = modalWrapSpinEl.offsetHeight;
|
// formerHeightRef.value = modalWrapSpinEl.offsetHeight;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (unref(fullScreenRef)) {
|
// if (unref(fullScreenRef)) {
|
||||||
modalWrapSpinEl.style.height = `${window.innerHeight - unref(context.extHeightRef)}px`;
|
// modalWrapSpinEl.style.height = `${window.innerHeight - unref(context.extHeightRef)}px`;
|
||||||
} else {
|
// } else {
|
||||||
modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`;
|
// modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
return { getWrapClassName, handleFullScreen, fullScreenRef };
|
return { getWrapClassName, handleFullScreen, fullScreenRef };
|
||||||
}
|
}
|
||||||
|
16
src/router/guard/httpGuard.ts
Normal file
16
src/router/guard/httpGuard.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { Router } from 'vue-router';
|
||||||
|
import { useProjectSetting } from '/@/hooks/setting';
|
||||||
|
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
||||||
|
|
||||||
|
export function createHttpGuard(router: Router) {
|
||||||
|
const { removeAllHttpPending } = useProjectSetting();
|
||||||
|
let axiosCanceler: Nullable<AxiosCanceler>;
|
||||||
|
if (removeAllHttpPending) {
|
||||||
|
axiosCanceler = new AxiosCanceler();
|
||||||
|
}
|
||||||
|
router.beforeEach(async () => {
|
||||||
|
// Switching the route will delete the previous request
|
||||||
|
removeAllHttpPending && axiosCanceler?.removeAllPending();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
@@ -1,64 +1,20 @@
|
|||||||
import { RouteLocationNormalized, Router } from 'vue-router';
|
import { Router } from 'vue-router';
|
||||||
|
|
||||||
import { Modal, notification } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { createProgressGuard } from './progressGuard';
|
import { createProgressGuard } from './progressGuard';
|
||||||
import { createPermissionGuard } from './permissionGuard';
|
import { createPermissionGuard } from './permissionGuard';
|
||||||
import { createPageLoadingGuard } from './pageLoadingGuard';
|
import { createPageLoadingGuard } from './pageLoadingGuard';
|
||||||
|
import { createTitleGuard } from './titleGuard';
|
||||||
import { useGlobSetting, useProjectSetting } from '/@/hooks/setting';
|
import { createMessageGuard } from './messageGuard';
|
||||||
|
import { createScrollGuard } from './scrollGuard';
|
||||||
import { setTitle } from '/@/utils/browser';
|
import { createHttpGuard } from './httpGuard';
|
||||||
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
import { createPageGuard } from './pageGuard';
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
|
||||||
import { REDIRECT_NAME } from '/@/router/constant';
|
|
||||||
import { setLastChangeTab } from '/@/logics/mitt/tabChange';
|
|
||||||
|
|
||||||
const { closeMessageOnSwitch, removeAllHttpPending } = useProjectSetting();
|
|
||||||
const globSetting = useGlobSetting();
|
|
||||||
|
|
||||||
const body = document.body;
|
|
||||||
|
|
||||||
const isHash = (href: string) => {
|
|
||||||
return /^#/.test(href);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createGuard(router: Router) {
|
export function createGuard(router: Router) {
|
||||||
let axiosCanceler: Nullable<AxiosCanceler>;
|
createPageGuard(router);
|
||||||
if (removeAllHttpPending) {
|
createHttpGuard(router);
|
||||||
axiosCanceler = new AxiosCanceler();
|
createScrollGuard(router);
|
||||||
}
|
createMessageGuard(router);
|
||||||
const loadedPageMap = new Map<string, boolean>();
|
createTitleGuard(router);
|
||||||
|
|
||||||
router.beforeEach(async (to) => {
|
|
||||||
to.meta.loaded = !!loadedPageMap.get(to.path);
|
|
||||||
// Notify routing changes
|
|
||||||
setLastChangeTab(to);
|
|
||||||
try {
|
|
||||||
if (closeMessageOnSwitch) {
|
|
||||||
Modal.destroyAll();
|
|
||||||
notification.destroy();
|
|
||||||
}
|
|
||||||
// Switching the route will delete the previous request
|
|
||||||
removeAllHttpPending && axiosCanceler!.removeAllPending();
|
|
||||||
} catch (error) {
|
|
||||||
console.warn('basic guard error:' + error);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
router.afterEach((to) => {
|
|
||||||
// scroll top
|
|
||||||
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
|
|
||||||
|
|
||||||
loadedPageMap.set(to.path, true);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
// change html title
|
|
||||||
to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title);
|
|
||||||
});
|
|
||||||
createPageLoadingGuard(router);
|
createPageLoadingGuard(router);
|
||||||
createProgressGuard(router);
|
createProgressGuard(router);
|
||||||
createPermissionGuard(router);
|
createPermissionGuard(router);
|
||||||
|
21
src/router/guard/messageGuard.ts
Normal file
21
src/router/guard/messageGuard.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import type { Router } from 'vue-router';
|
||||||
|
import { useProjectSetting } from '/@/hooks/setting';
|
||||||
|
import { Modal, notification } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { warn } from '/@/utils/log';
|
||||||
|
|
||||||
|
export function createMessageGuard(router: Router) {
|
||||||
|
const { closeMessageOnSwitch } = useProjectSetting();
|
||||||
|
|
||||||
|
router.beforeEach(async () => {
|
||||||
|
try {
|
||||||
|
if (closeMessageOnSwitch) {
|
||||||
|
Modal.destroyAll();
|
||||||
|
notification.destroy();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
warn('message guard error:' + error);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
18
src/router/guard/pageGuard.ts
Normal file
18
src/router/guard/pageGuard.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { Router } from 'vue-router';
|
||||||
|
import { setLastChangeTab } from '/@/logics/mitt/tabChange';
|
||||||
|
|
||||||
|
export function createPageGuard(router: Router) {
|
||||||
|
const loadedPageMap = new Map<string, boolean>();
|
||||||
|
|
||||||
|
router.beforeEach(async (to) => {
|
||||||
|
to.meta.loaded = !!loadedPageMap.get(to.path);
|
||||||
|
// Notify routing changes
|
||||||
|
setLastChangeTab(to);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.afterEach((to) => {
|
||||||
|
loadedPageMap.set(to.path, true);
|
||||||
|
});
|
||||||
|
}
|
15
src/router/guard/scrollGuard.ts
Normal file
15
src/router/guard/scrollGuard.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import type { RouteLocationNormalized, Router } from 'vue-router';
|
||||||
|
|
||||||
|
const isHash = (href: string) => {
|
||||||
|
return /^#/.test(href);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createScrollGuard(router: Router) {
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
|
router.afterEach(async (to) => {
|
||||||
|
// scroll top
|
||||||
|
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
18
src/router/guard/titleGuard.ts
Normal file
18
src/router/guard/titleGuard.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { Router } from 'vue-router';
|
||||||
|
|
||||||
|
import { useGlobSetting } from '/@/hooks/setting';
|
||||||
|
|
||||||
|
import { setTitle } from '/@/utils/browser';
|
||||||
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
|
import { REDIRECT_NAME } from '/@/router/constant';
|
||||||
|
|
||||||
|
const globSetting = useGlobSetting();
|
||||||
|
|
||||||
|
export function createTitleGuard(router: Router) {
|
||||||
|
router.afterEach(async (to) => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
to.name !== REDIRECT_NAME && setTitle(t(to.meta.title), globSetting.title);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
@@ -8,8 +8,5 @@
|
|||||||
import { BasicModal } from '/@/components/Modal';
|
import { BasicModal } from '/@/components/Modal';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { BasicModal },
|
components: { BasicModal },
|
||||||
setup() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Reference in New Issue
Block a user