Skip to content

Commit

Permalink
feat: init router safe guard
Browse files Browse the repository at this point in the history
  • Loading branch information
hengwujun128 committed Apr 11, 2024
1 parent fa5803f commit e6a568d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 14 deletions.
8 changes: 4 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
}
},
"i18n-ally.localesPaths": ["src/locales/lang"],
Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function bootstrap() {
setupRouter(app);

// router-guard
// 路由守卫
// 路由守卫(全局守卫)
setupRouterGuard(router);

// Register global directive
Expand Down
14 changes: 13 additions & 1 deletion src/router/guard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ import { createParamMenuGuard } from './paramMenuGuard';

// Don't change the order of creation
export function setupRouterGuard(router: Router) {
// 改变页面的加载状态: 修改to.meta.loaded, 添加loadedPageMap
createPageGuard(router);
// 页面 loading 状态: openPageLoading
createPageLoadingGuard(router);

// 切换路由时,中断正在进行的http请求
createHttpGuard(router);
//
createScrollGuard(router);
createMessageGuard(router);
createProgressGuard(router);
Expand Down Expand Up @@ -48,17 +53,21 @@ function createPageGuard(router: Router) {

// Used to handle page loading status
function createPageLoadingGuard(router: Router) {
// 在全局路由守卫中使用 pinia store
const userStore = useUserStoreWithOut();
const appStore = useAppStoreWithOut();
const { getOpenPageLoading } = useTransitionSetting();

router.beforeEach(async (to) => {
// 没有token ,直接跳过守卫
if (!userStore.getToken) {
return true;
}
// 页面加载过,也直接跳过守卫( 这样就只针对初次加载的页面有效)
if (to.meta.loaded) {
return true;
}

// 对 computed 进行 unref()
if (unref(getOpenPageLoading)) {
appStore.setPageLoadingAction(true);
return true;
Expand All @@ -84,8 +93,11 @@ function createPageLoadingGuard(router: Router) {
*/
function createHttpGuard(router: Router) {
const { removeAllHttpPending } = projectSetting;

let axiosCanceler: Nullable<AxiosCanceler>;
// 如果配置了 取消 http 请求 ,就实例化 AxiosCanceler
if (removeAllHttpPending) {
// 虽然是不同的 AxiosCanceler 实例,但是 removeAllPending() 访问的全局的属性
axiosCanceler = new AxiosCanceler();
}
router.beforeEach(async () => {
Expand Down
3 changes: 2 additions & 1 deletion src/router/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Object.keys(modules).forEach((key) => {
routeModuleList.push(...modList);
});

// 在路由守卫中添加的动态路由
export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList];

// 根路由
Expand All @@ -43,7 +44,7 @@ export const LoginRoute: AppRouteRecordRaw = {
export const basicRoutes = [
LoginRoute,
RootRoute,
...mainOutRoutes,
...mainOutRoutes, // 框架以外的页面
REDIRECT_ROUTE,
PAGE_NOT_FOUND_ROUTE,
];
9 changes: 5 additions & 4 deletions src/utils/http/axios/Axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ export class VAxios {

// Request interceptor configuration processing
this.axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// If cancel repeat request is turned on, then cancel repeat request is prohibited
const requestOptions = (config as unknown as any).requestOptions ?? this.options.requestOptions;
// If cancel repeat request is turned on, then cancel repeat request is prohibited
const requestOptions =
(config as unknown as any).requestOptions ?? this.options.requestOptions;
const ignoreCancelToken = requestOptions?.ignoreCancelToken ?? true;

// NOTE: 在 http 请求拦截器中,把 axios 的config直接添加到 axiosCanceler 中
!ignoreCancelToken && axiosCanceler.addPending(config);

if (requestInterceptors && isFunction(requestInterceptors)) {
Expand Down Expand Up @@ -202,7 +203,7 @@ export class VAxios {
if (config.cancelToken) {
conf.cancelToken = config.cancelToken;
}

if (config.signal) {
conf.signal = config.signal;
}
Expand Down
11 changes: 8 additions & 3 deletions src/utils/http/axios/axiosCancel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AxiosRequestConfig } from 'axios';

// 用于存储每个请求的标识和取消函数
// 用于存储每个请求的标识和取消函数(global settings)
const pendingMap = new Map<string, AbortController>();

const getPendingUrl = (config: AxiosRequestConfig): string => {
Expand All @@ -13,12 +13,17 @@ export class AxiosCanceler {
* @param config 请求配置
*/
public addPending(config: AxiosRequestConfig): void {
// 每次添加config 都先清除
this.removePending(config);
// 获取axios 配置中的请求 url 和请求方法,并作为key 添加到pendingMap 中
const url = getPendingUrl(config);
// abortController js API, 用于取消请求
const controller = new AbortController();
// 向 axios 中注入新的属性 single, 其实就是abortController 的 single 属性
config.signal = config.signal || controller.signal;
// 存储每个请求的标识
if (!pendingMap.has(url)) {
// 如果当前请求不在等待中,将其添加到等待中
// 如果当前请求不在等待中,将其添加到等待中, 每个请求 api ,就配置一个 AbortController 实例
pendingMap.set(url, controller);
}
}
Expand All @@ -45,7 +50,7 @@ export class AxiosCanceler {
// 如果当前请求在等待中,取消它并将其从等待中移除
const abortController = pendingMap.get(url);
if (abortController) {
abortController.abort(url);
abortController.abort(url); // NOTE: 可以不用传参
}
pendingMap.delete(url);
}
Expand Down
3 changes: 3 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineApplicationConfig } from '@vben/vite-config';

// TIPS: vite.config.ts 配置作为插件进行封装

export default defineApplicationConfig({
overrides: {
optimizeDeps: {
Expand Down Expand Up @@ -32,5 +34,6 @@ export default defineApplicationConfig({
},
},
},
base: '/vben',
},
});

0 comments on commit e6a568d

Please sign in to comment.