From 7a15b1b3b4cec177357181bcb7b0c6d77b9ca349 Mon Sep 17 00:00:00 2001 From: wang <1509326266@qq.com> Date: Mon, 19 Aug 2024 22:13:50 +0800 Subject: [PATCH] feat(packages): perfect routing method --- packages/simple-router/src/router.tsx | 45 ++++++++++++++++++++++----- src/router/elegant/transform.ts | 6 ++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/packages/simple-router/src/router.tsx b/packages/simple-router/src/router.tsx index faeb3e5..6e83022 100644 --- a/packages/simple-router/src/router.tsx +++ b/packages/simple-router/src/router.tsx @@ -54,10 +54,10 @@ class CreateRouter { }); this.reactRouter.getBlocker('beforeGuard', (arg: Parameters[0]) => - this.onBeforeRouteChange(arg, beforeEach, firstInit) + this.#onBeforeRouteChange(arg, beforeEach, firstInit) ); - this.reactRouter.subscribe((state: RouterState) => this.afterRouteChange(state, afterEach)); + this.reactRouter.subscribe((state: RouterState) => this.#afterRouteChange(state, afterEach)); this.initReactRoutes = initReactRoutes; this.getReactRoutes = getReactRoutes; Promise.resolve().then(async () => { @@ -91,7 +91,7 @@ class CreateRouter { this.reactRouter._internalSetRoutes([...this.initReactRoutes, ...this.reactRoutes]); } - onBeforeRouteChange = ( + #onBeforeRouteChange = ( { currentLocation, nextLocation }: Parameters[0], beforeEach: RouterOptions['beforeEach'], firstInit: (allNames: string[]) => void @@ -111,7 +111,14 @@ class CreateRouter { const to = this.resolve(nextLocation); - if (to.matched[0]?.redirect === this.currentRoute.path) return true; + const matchedRoutes = to.matched; + const nextRoute = matchedRoutes[matchedRoutes.length - 1]; + + const finalPath = getFullPath(nextRoute); + + if (finalPath === this.currentRoute.path || matchedRoutes[0]?.redirect === this.currentRoute.path) { + return true; + } const next = (param?: boolean | string) => { if (!param) return false; @@ -211,7 +218,7 @@ class CreateRouter { return this.getRoutes().find(route => route.name === key)?.meta || null; } - afterRouteChange = (state: RouterState, afterEach: RouterOptions['afterEach']) => { + #afterRouteChange = (state: RouterState, afterEach: RouterOptions['afterEach']) => { if (state.navigation.state === 'idle') { const from = this.currentRoute; this.currentRoute = this.resolve(state.location); @@ -241,13 +248,25 @@ class CreateRouter { return this.matcher.getRecordMatcher(name)?.record; } - push(to: RouteLocationNamedRaw | string) { + push(to: RouteLocationNamedRaw | string | Location, replace?: true) { const target = typeof to === 'string' ? to : this.resolve(to).fullPath; if (target !== this.currentRoute.fullPath) { - this.reactRouter.navigate(target); + this.reactRouter.navigate(target, { replace }); } } + + back() { + this.go(-1); + } + + forwardRef() { + this.go(1); + } + + go(delta: number) { + this.reactRouter.navigate(delta); + } } export default CreateRouter; @@ -256,3 +275,15 @@ function cleanParams(params: Record | undefined): Record value !== null)); } + +function getFullPath(route: RouteRecordNormalized | ElegantConstRoute): string { + // 如果当前 route 存在并且有 children + if (route && route.children && route.children.length > 0) { + // 获取第一个子路由 + const firstChild = route.children[0]; + // 递归调用,继续拼接子路由的 path + return `${route.path}/${getFullPath(firstChild)}`; + } + // 如果没有 children,返回当前 route 的 path + return route.path; +} diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts index a9b288c..0c72cc1 100644 --- a/src/router/elegant/transform.ts +++ b/src/router/elegant/transform.ts @@ -167,7 +167,7 @@ export function transformElegantRouteToReactRoute( } - + if (children?.length) { @@ -182,11 +182,13 @@ export function transformElegantRouteToReactRoute( }else if (redirectTo) { reactRoute.loader=()=>redirect(redirectTo) } - + if (loader) { reactRoute.loader = () => loader } + + if (layout) { return {