mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-01-23 11:50:20 +08:00
perf(router): reduce the number of guard files
This commit is contained in:
parent
941ad59759
commit
327d71b8fb
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -129,6 +129,7 @@
|
||||
"qrcode",
|
||||
"sider",
|
||||
"pinia",
|
||||
"sider"
|
||||
"sider",
|
||||
"nprogress"
|
||||
]
|
||||
}
|
||||
|
@ -50,7 +50,7 @@
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"pinia": "2.0.0-beta.3",
|
||||
"pinia": "^2.0.0-beta.3",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"sortablejs": "^1.13.0",
|
||||
|
@ -10,7 +10,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { AppProvider } from '/@/components/Application';
|
||||
|
||||
import { useTitle } from '/@/hooks/web/useTitle';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
|
@ -137,7 +137,7 @@
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal != oldVal) visibleRef.value = newVal;
|
||||
if (newVal !== oldVal) visibleRef.value = newVal;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
@ -19,25 +19,18 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { MenuState } from './types';
|
||||
|
||||
import { computed, defineComponent, unref, reactive, watch, toRefs, ref } from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import BasicSubMenuItem from './components/BasicSubMenuItem.vue';
|
||||
|
||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||
|
||||
import { useOpenKeys } from './useOpenKeys';
|
||||
import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router';
|
||||
|
||||
import { isFunction } from '/@/utils/is';
|
||||
|
||||
import { basicProps } from './props';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { REDIRECT_NAME } from '/@/router/constant';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { getCurrentParentPath } from '/@/router/menus';
|
||||
|
||||
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
// Need
|
||||
Button as AntButton,
|
||||
Input,
|
||||
Layout,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
const compList = [AntButton.Group];
|
||||
@ -14,5 +15,5 @@ export function registerGlobComp(app: App) {
|
||||
app.component(comp.name || comp.displayName, comp);
|
||||
});
|
||||
|
||||
app.use(Input).use(Button);
|
||||
app.use(Input).use(Button).use(Layout);
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { watch, unref, ref, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { useThrottleFn } from '@vueuse/core';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
|
||||
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
|
@ -81,24 +81,19 @@
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
import { defineComponent, onMounted, ref, computed, unref } from 'vue';
|
||||
|
||||
import { ScrollContainer } from '/@/components/Container';
|
||||
import { SimpleMenuTag } from '/@/components/SimpleMenu';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import Trigger from '../trigger/HeaderTrigger.vue';
|
||||
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDragLine } from './useLayoutSider';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
|
||||
import { SIDE_BAR_SHOW_TIT_MINI_WIDTH, SIDE_BAR_MINI_WIDTH } from '/@/enums/appEnum';
|
||||
|
||||
import clickOutside from '/@/directives/clickOutside';
|
||||
import { getShallowMenus, getChildrenMenus, getCurrentParentPath } from '/@/router/menus';
|
||||
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
||||
|
@ -1,9 +1,7 @@
|
||||
import '/@/design/index.less';
|
||||
import '/@/design/tailwind.css';
|
||||
|
||||
// Register icon sprite
|
||||
import 'virtual:svg-icons-register';
|
||||
|
||||
import App from './App.vue';
|
||||
import { createApp } from 'vue';
|
||||
import { initAppConfigStore } from '/@/logics/initAppConfig';
|
||||
@ -42,7 +40,7 @@ async function bootstrap() {
|
||||
setupRouter(app);
|
||||
|
||||
// router-guard
|
||||
setupRouterGuard();
|
||||
setupRouterGuard(router);
|
||||
|
||||
// Register global directive
|
||||
setupGlobDirectives(app);
|
||||
|
@ -1,20 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
|
||||
/**
|
||||
* The interface used to close the current page to complete the request when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createHttpGuard(router: Router) {
|
||||
const { removeAllHttpPending } = projectSetting;
|
||||
let axiosCanceler: Nullable<AxiosCanceler>;
|
||||
if (removeAllHttpPending) {
|
||||
axiosCanceler = new AxiosCanceler();
|
||||
}
|
||||
router.beforeEach(async () => {
|
||||
// Switching the route will delete the previous request
|
||||
axiosCanceler?.removeAllPending();
|
||||
return true;
|
||||
});
|
||||
}
|
@ -1,15 +1,19 @@
|
||||
import { router } from '/@/router';
|
||||
|
||||
import { createProgressGuard } from './progressGuard';
|
||||
import type { Router, RouteLocationNormalized } from 'vue-router';
|
||||
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import { warn } from '/@/utils/log';
|
||||
import { unref } from 'vue';
|
||||
import { setRouteChange } from '/@/logics/mitt/routeChange';
|
||||
import { createPermissionGuard } from './permissionGuard';
|
||||
import { createPageLoadingGuard } from './pageLoadingGuard';
|
||||
import { createMessageGuard } from './messageGuard';
|
||||
import { createScrollGuard } from './scrollGuard';
|
||||
import { createHttpGuard } from './httpGuard';
|
||||
import { createPageGuard } from './pageGuard';
|
||||
import { createStateGuard } from './stateGuard';
|
||||
import nProgress from 'nprogress';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
|
||||
export function setupRouterGuard() {
|
||||
// Don't change the order of creation
|
||||
export function setupRouterGuard(router: Router) {
|
||||
createPageGuard(router);
|
||||
createPageLoadingGuard(router);
|
||||
createHttpGuard(router);
|
||||
@ -19,3 +23,123 @@ export function setupRouterGuard() {
|
||||
createPermissionGuard(router);
|
||||
createStateGuard(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks for handling page state
|
||||
*/
|
||||
function createPageGuard(router: Router) {
|
||||
const loadedPageMap = new Map<string, boolean>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
// The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing
|
||||
to.meta.loaded = !!loadedPageMap.get(to.path);
|
||||
// Notify routing changes
|
||||
setRouteChange(to);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach((to) => {
|
||||
loadedPageMap.set(to.path, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Used to handle page loading status
|
||||
function createPageLoadingGuard(router: Router) {
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const appStore = useAppStoreWidthOut();
|
||||
const { getOpenPageLoading } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (!userStore.getToken) {
|
||||
return true;
|
||||
}
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unref(getOpenPageLoading)) {
|
||||
appStore.setPageLoadingAction(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
router.afterEach(async () => {
|
||||
if (unref(getOpenPageLoading)) {
|
||||
// TODO Looking for a better way
|
||||
// The timer simulates the loading time to prevent flashing too fast,
|
||||
setTimeout(() => {
|
||||
appStore.setPageLoading(false);
|
||||
}, 220);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface used to close the current page to complete the request when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
function createHttpGuard(router: Router) {
|
||||
const { removeAllHttpPending } = projectSetting;
|
||||
let axiosCanceler: Nullable<AxiosCanceler>;
|
||||
if (removeAllHttpPending) {
|
||||
axiosCanceler = new AxiosCanceler();
|
||||
}
|
||||
router.beforeEach(async () => {
|
||||
// Switching the route will delete the previous request
|
||||
axiosCanceler?.removeAllPending();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Routing switch back to the top
|
||||
function createScrollGuard(router: Router) {
|
||||
const isHash = (href: string) => {
|
||||
return /^#/.test(href);
|
||||
};
|
||||
|
||||
const body = document.body;
|
||||
|
||||
router.afterEach(async (to) => {
|
||||
// scroll top
|
||||
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to close the message instance when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createMessageGuard(router: Router) {
|
||||
const { closeMessageOnSwitch } = projectSetting;
|
||||
|
||||
router.beforeEach(async () => {
|
||||
try {
|
||||
if (closeMessageOnSwitch) {
|
||||
Modal.destroyAll();
|
||||
notification.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
warn('message guard error:' + error);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function createProgressGuard(router: Router) {
|
||||
const { getOpenNProgress } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
unref(getOpenNProgress) && nProgress.start();
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach(async () => {
|
||||
unref(getOpenNProgress) && nProgress.done();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
import { warn } from '/@/utils/log';
|
||||
|
||||
/**
|
||||
* Used to close the message instance when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createMessageGuard(router: Router) {
|
||||
const { closeMessageOnSwitch } = projectSetting;
|
||||
|
||||
router.beforeEach(async () => {
|
||||
try {
|
||||
if (closeMessageOnSwitch) {
|
||||
Modal.destroyAll();
|
||||
notification.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
warn('message guard error:' + error);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { setRouteChange } from '/@/logics/mitt/routeChange';
|
||||
|
||||
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
|
||||
setRouteChange(to);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach((to) => {
|
||||
loadedPageMap.set(to.path, true);
|
||||
});
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
import { unref } from 'vue';
|
||||
|
||||
export function createPageLoadingGuard(router: Router) {
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const appStore = useAppStoreWidthOut();
|
||||
const { getOpenPageLoading } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (!userStore.getToken) {
|
||||
return true;
|
||||
}
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unref(getOpenPageLoading)) {
|
||||
appStore.setPageLoadingAction(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
router.afterEach(async () => {
|
||||
if (unref(getOpenPageLoading)) {
|
||||
setTimeout(() => {
|
||||
appStore.setPageLoading(false);
|
||||
}, 220);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
@ -32,13 +32,11 @@ export function createPermissionGuard(router: Router) {
|
||||
// token does not exist
|
||||
if (!token) {
|
||||
// You can access without permission. You need to set the routing meta.ignoreAuth to true
|
||||
if (
|
||||
to.meta.ignoreAuth
|
||||
// || to.name === FULL_PAGE_NOT_FOUND_ROUTE.name
|
||||
) {
|
||||
if (to.meta.ignoreAuth) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// redirect login page
|
||||
const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
|
||||
path: LOGIN_PATH,
|
||||
@ -53,10 +51,12 @@ export function createPermissionGuard(router: Router) {
|
||||
next(redirectData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (permissionStore.getIsDynamicAddedRoute) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const routes = await permissionStore.buildRoutesAction();
|
||||
|
||||
routes.forEach((route) => {
|
||||
|
@ -1,22 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
|
||||
import nProgress from 'nprogress';
|
||||
|
||||
import { unref } from 'vue';
|
||||
|
||||
export function createProgressGuard(router: Router) {
|
||||
const { getOpenNProgress } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.meta.loaded) return true;
|
||||
unref(getOpenNProgress) && nProgress.start();
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach(async () => {
|
||||
// if (to.meta.loaded) return true;
|
||||
unref(getOpenNProgress) && nProgress.done();
|
||||
return true;
|
||||
});
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
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;
|
||||
});
|
||||
}
|
@ -9,7 +9,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
|
||||
export type LayoutMapKey = 'LAYOUT';
|
||||
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
|
||||
|
||||
const LayoutMap = new Map<String, () => Promise<typeof import('*.vue')>>();
|
||||
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>();
|
||||
|
||||
LayoutMap.set('LAYOUT', LAYOUT);
|
||||
LayoutMap.set('IFRAME', IFRAME);
|
||||
@ -27,7 +27,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
|
||||
const { component, name } = item;
|
||||
const { children } = item;
|
||||
if (component) {
|
||||
const layoutFound = LayoutMap.get(component);
|
||||
const layoutFound = LayoutMap.get(component as string);
|
||||
if (layoutFound) {
|
||||
item.component = layoutFound;
|
||||
} else {
|
||||
@ -66,10 +66,10 @@ function dynamicImport(
|
||||
// Turn background objects into routing objects
|
||||
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] {
|
||||
routeList.forEach((route) => {
|
||||
if (route.component) {
|
||||
if ((route.component as string).toUpperCase() === 'LAYOUT') {
|
||||
//route.component = LayoutMap.get(route.component as LayoutMapKey);
|
||||
route.component = LayoutMap.get((route.component as string).toUpperCase() as LayoutMapKey);
|
||||
const component = route.component as string;
|
||||
if (component) {
|
||||
if (component.toUpperCase() === 'LAYOUT') {
|
||||
route.component = LayoutMap.get(component.toUpperCase());
|
||||
} else {
|
||||
route.children = [cloneDeep(route)];
|
||||
route.component = LAYOUT;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { App } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
const store = createPinia();
|
||||
|
||||
export function setupStore(app: App<Element>) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
/**
|
||||
* https://github.com/developit/mitt
|
||||
* copy to https://github.com/developit/mitt
|
||||
* Expand clear method
|
||||
*/
|
||||
|
||||
export type EventType = string | symbol;
|
||||
|
@ -9278,7 +9278,7 @@ pify@^4.0.1:
|
||||
resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
||||
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
||||
|
||||
pinia@2.0.0-beta.3:
|
||||
pinia@^2.0.0-beta.3:
|
||||
version "2.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.0-beta.3.tgz#c6f0d07da54dc5aa237f4cc9281898e927b33d16"
|
||||
integrity sha512-4ygKhe9FrYD69tJ7nSdgHm9Ldb0aM/Nzyb8Qz/RZuzOyOr85jWHNmCAhCytWy0l9C4/ypGJYCEJ3vuZfyWjcZA==
|
||||
|
Loading…
Reference in New Issue
Block a user