@@ -10,6 +10,7 @@ import { START_LOCATION_NORMALIZED } from './types';
1010import { RouterContext } from './hooks/useRouter' ;
1111import { RouteContext } from './hooks/useRoute' ;
1212import { warn } from './warning' ;
13+ import type { RouteRecordRaw } from './matcher/types'
1314
1415const historyCreatorMap : Record <
1516 'hash' | 'history' | 'memory' ,
@@ -89,9 +90,35 @@ class CreateRouter {
8990 } ) ;
9091
9192 // Update react-router's routes
93+ this . #changeRoutes( )
94+ }
95+
96+ #changeRoutes( ) {
9297 this . reactRouter . _internalSetRoutes ( [ ...this . initReactRoutes , ...this . reactRoutes ] ) ;
9398 }
9499
100+ removeRoute ( name : string ) {
101+ const matched = this . matcher . getRecordMatcher ( name )
102+ if ( ! matched ) return
103+ if ( matched . parent ) {
104+
105+ const parentNames = findParentNames ( matched . parent )
106+ let routes = this . reactRoutes
107+
108+ parentNames . forEach ( name => {
109+ const finalRoute = routes . find ( route => route . id === name )
110+ if ( finalRoute && finalRoute . children ) routes = finalRoute . children
111+ } )
112+ removeElement ( routes , matched . name )
113+
114+ } else {
115+ this . reactRoutes = this . reactRoutes . filter ( route => route . id !== matched . record . name )
116+ }
117+ this . #changeRoutes( )
118+ this . matcher . removeRoute ( name ) ;
119+
120+ }
121+
95122 #onBeforeRouteChange = (
96123 { currentLocation, nextLocation } : Parameters < BlockerFunction > [ 0 ] ,
97124 beforeEach : RouterOptions [ 'beforeEach' ] ,
@@ -112,18 +139,25 @@ class CreateRouter {
112139
113140 const to = this . resolve ( nextLocation ) ;
114141
115- const matchedRoutes = to . matched ;
116- const nextRoute = matchedRoutes [ matchedRoutes . length - 1 ] ;
142+ if ( to . redirect ) {
143+ if ( to . redirect . startsWith ( '/' ) ) {
144+ if ( to . redirect === this . currentRoute . fullPath ) {
145+ return true
146+ }
147+ } else {
148+ const finalRoute = to . matched [ to . matched . length - 1 ]
117149
118- const finalPath = getFullPath ( nextRoute ) ;
119150
120- if ( finalPath === this . currentRoute . path || matchedRoutes [ 0 ] ?. redirect === this . currentRoute . path ) {
121- return true ;
151+ const finalPath = getFullPath ( finalRoute )
152+
153+ if ( finalPath === this . currentRoute . fullPath ) return true
154+ }
122155 }
123156
124157 return beforeEach ( to , this . currentRoute , this . #next) ;
125158 } ;
126159
160+
127161 #next( param ?: boolean | string | Location | RouteLocationNamedRaw ) {
128162 if ( ! param ) return false ;
129163 if ( typeof param === 'string' ) {
@@ -224,7 +258,7 @@ class CreateRouter {
224258 * @param key Route key
225259 */
226260 getRouteMetaByKey ( key : string ) {
227- return this . getRoutes ( ) . find ( route => route . name === key ) ?. meta || null ;
261+ return this . getRoutes ( ) . find ( route => route . name === key ) ?. meta ;
228262 }
229263
230264 #afterRouteChange = ( state : RouterState , afterEach : RouterOptions [ 'afterEach' ] ) => {
@@ -253,7 +287,7 @@ class CreateRouter {
253287 * @param name - The name of the route.
254288 * @returns The route record or false if not found.
255289 */
256- getRouteByName ( name : string ) : RouteRecordNormalized | undefined {
290+ getRouteByName ( name : string ) {
257291 return this . matcher . getRecordMatcher ( name ) ?. record ;
258292 }
259293
@@ -285,13 +319,43 @@ function cleanParams(params: Record<string, any> | undefined): Record<string, an
285319 return Object . fromEntries ( Object . entries ( params ) . filter ( ( [ _ , value ] ) => value !== null ) ) ;
286320}
287321
288- function getFullPath ( route : RouteRecordNormalized | ElegantConstRoute ) : string {
322+
323+
324+
325+
326+ function findParentNames ( matched : RouteRecordRaw | undefined ) : ( string | undefined ) [ ] {
327+ const parentNames : ( string | undefined ) [ ] = [ ]
328+
329+ function helper ( current : RouteRecordRaw | undefined ) {
330+ if ( current ?. parent ) {
331+ helper ( current . parent )
332+ }
333+ parentNames . push ( current ?. name )
334+ }
335+
336+ helper ( matched )
337+
338+ return parentNames
339+ }
340+
341+
342+ function removeElement ( arr : RouteObject [ ] , name : string | undefined ) {
343+ const index = arr . findIndex ( route => route . id === name ) ;
344+ if ( index !== - 1 ) {
345+ arr . splice ( index , 1 ) ;
346+ }
347+ return arr ;
348+ }
349+
350+
351+ function getFullPath ( route : RouteRecordNormalized | ElegantConstRoute ) : string {
289352 // 如果当前 route 存在并且有 children
290- if ( route && route . children && route . children . length > 0 ) {
353+ if ( route && route . redirect && route . children && route . children . length > 0 ) {
291354 // 获取第一个子路由
292- const firstChild = route . children [ 0 ] ;
355+ const firstChild = route . children . find ( child => child . path === route . redirect )
293356 // 递归调用,继续拼接子路由的 path
294- return `${ route . path } /${ getFullPath ( firstChild ) } ` ;
357+ if ( firstChild )
358+ return `${ route . path } /${ getFullPath ( firstChild ) } ` ;
295359 }
296360 // 如果没有 children,返回当前 route 的 path
297361 return route . path ;
0 commit comments