index.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import type { Router, RouteLocationNormalized } from 'vue-router';
  2. import { useAppStoreWithOut } from '/@/store/modules/app';
  3. import { useUserStoreWithOut } from '/@/store/modules/user';
  4. import { useVentStore } from '/@/store/modules/vent';
  5. import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
  6. import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
  7. import { Modal, notification } from 'ant-design-vue';
  8. import { warn } from '/@/utils/log';
  9. import { unref } from 'vue';
  10. import { setRouteChange } from '/@/logics/mitt/routeChange';
  11. import { createPermissionGuard } from './permissionGuard';
  12. import { createStateGuard } from './stateGuard';
  13. import nProgress from 'nprogress';
  14. import projectSetting from '/@/settings/projectSetting';
  15. import { createParamMenuGuard } from './paramMenuGuard';
  16. import { RootRoute } from '/@/router/routes';
  17. import { useGlobSetting } from '/@/hooks/setting';
  18. import { PageEnum } from '/@/enums/pageEnum';
  19. // Don't change the order of creation
  20. export function setupRouterGuard(router: Router) {
  21. createPageGuard(router);
  22. createPageLoadingGuard(router);
  23. createHttpGuard(router);
  24. createScrollGuard(router);
  25. createMessageGuard(router);
  26. createProgressGuard(router);
  27. createPermissionGuard(router);
  28. createParamMenuGuard(router); // must after createPermissionGuard (menu has been built.)
  29. createStateGuard(router);
  30. }
  31. const glob = useGlobSetting();
  32. RootRoute.redirect = glob.homePath || PageEnum.BASE_HOME;
  33. /**
  34. * Hooks for handling page state
  35. */
  36. function createPageGuard(router: Router) {
  37. const loadedPageMap = new Map<string, boolean>();
  38. router.beforeEach(async (to) => {
  39. // The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing
  40. to.meta.loaded = !!loadedPageMap.get(to.path);
  41. // Notify routing changes
  42. setRouteChange(to);
  43. return true;
  44. });
  45. router.afterEach((to) => {
  46. loadedPageMap.set(to.path, true);
  47. });
  48. }
  49. // Used to handle page loading status
  50. function createPageLoadingGuard(router: Router) {
  51. const ventStore = useVentStore();
  52. const userStore = useUserStoreWithOut();
  53. const appStore = useAppStoreWithOut();
  54. const { getOpenPageLoading } = useTransitionSetting();
  55. router.beforeEach(async (to) => {
  56. if (!userStore.getToken) {
  57. return true;
  58. }
  59. if (to.meta.loaded) {
  60. return true;
  61. }
  62. if (!ventStore.allTableHeaderColumns) await ventStore.setAllTableHeaderColumns();
  63. if (unref(getOpenPageLoading)) {
  64. appStore.setPageLoadingAction(true);
  65. return true;
  66. }
  67. return true;
  68. });
  69. router.afterEach(async () => {
  70. if (unref(getOpenPageLoading)) {
  71. // TODO Looking for a better way
  72. // The timer simulates the loading time to prevent flashing too fast,
  73. setTimeout(() => {
  74. appStore.setPageLoading(false);
  75. }, 220);
  76. }
  77. return true;
  78. });
  79. }
  80. /**
  81. * The interface used to close the current page to complete the request when the route is switched
  82. * @param router
  83. */
  84. function createHttpGuard(router: Router) {
  85. const { removeAllHttpPending } = projectSetting;
  86. let axiosCanceler: Nullable<AxiosCanceler>;
  87. if (removeAllHttpPending) {
  88. axiosCanceler = new AxiosCanceler();
  89. }
  90. router.beforeEach(async () => {
  91. // Switching the route will delete the previous request
  92. axiosCanceler?.removeAllPending();
  93. return true;
  94. });
  95. }
  96. // Routing switch back to the top
  97. function createScrollGuard(router: Router) {
  98. const isHash = (href: string) => {
  99. return /^#/.test(href);
  100. };
  101. const body = document.body;
  102. router.afterEach(async (to) => {
  103. // scroll top
  104. isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
  105. return true;
  106. });
  107. }
  108. /**
  109. * Used to close the message instance when the route is switched
  110. * @param router
  111. */
  112. export function createMessageGuard(router: Router) {
  113. const { closeMessageOnSwitch } = projectSetting;
  114. router.beforeEach(async () => {
  115. try {
  116. if (closeMessageOnSwitch) {
  117. Modal.destroyAll();
  118. notification.destroy();
  119. }
  120. } catch (error) {
  121. warn('message guard error:' + error);
  122. }
  123. return true;
  124. });
  125. }
  126. export function createProgressGuard(router: Router) {
  127. const { getOpenNProgress } = useTransitionSetting();
  128. router.beforeEach(async (to) => {
  129. if (to.meta.loaded) {
  130. return true;
  131. }
  132. unref(getOpenNProgress) && nProgress.start();
  133. return true;
  134. });
  135. router.afterEach(async () => {
  136. unref(getOpenNProgress) && nProgress.done();
  137. return true;
  138. });
  139. }