Skip to content

Commit a75c25e

Browse files
committed
feat(packages): add remove route & If the route to be jumped is the current route, no jump occurs
1 parent f1dcd68 commit a75c25e

File tree

6 files changed

+95
-17
lines changed

6 files changed

+95
-17
lines changed

packages/simple-router/src/matcher/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class CreateRouterMatcher {
6464
const parentPath = parent.record.path as string;
6565
const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/';
6666
normalizedRecord.path = parent.record.path + (path && connectingSlash + path);
67+
6768
}
6869

6970
// create the object beforehand, so it can be passed to children
@@ -190,6 +191,7 @@ class CreateRouterMatcher {
190191
path,
191192
hash: location.hash,
192193
component,
194+
redirect: matcher.record.redirect,
193195
matched,
194196
query,
195197
meta: mergeMetaFields(matched)
@@ -202,8 +204,7 @@ class CreateRouterMatcher {
202204
* @returns An array of route names.
203205
*/
204206
getAllRouteNames() {
205-
const names = Array.from(this.matcherMap.keys());
206-
return names;
207+
return Array.from(this.matcherMap.keys())
207208
}
208209

209210
/**
@@ -212,6 +213,7 @@ class CreateRouterMatcher {
212213
* @param matcher - The matcher object to insert.
213214
*/
214215
insertMatcher(matcher: RouteRecordRaw) {
216+
215217
if (matcher.record.path === '*') {
216218
this.matchers.unshift(matcher);
217219
} else {

packages/simple-router/src/matcher/pathMatcher.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export function createRouteRecordMatcher(record: RouteRecordNormalized, parent?:
44
record,
55
parent,
66
// these needs to be populated by the parent
7-
children: []
7+
children: [],
8+
name:record.name
89
};
910

1011
if (parent) {

packages/simple-router/src/matcher/shared.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,16 @@ export function generatePath(pathTemplate: string, params: { [key: string]: stri
4141
* @returns the normalized version
4242
*/
4343
export function normalizeRouteRecord(record: ElegantConstRoute): RouteRecordNormalized {
44+
4445
return {
45-
redirect: record.redirect,
46+
redirect: record.redirect||record.children&&record.children[0].path,
4647
path: record.path || '',
4748
name: record.name,
4849
meta: record.meta || {},
49-
children: record.children || [],
50+
children: record.children?.map(child => {
51+
child.redirect=child.redirect||child.children&&child.children[0].path
52+
return child
53+
}) || [],
5054
component: record.component
5155
};
5256
}

packages/simple-router/src/matcher/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export interface RouteRecordRaw {
1919
record: RouteRecordNormalized;
2020
children: RouteRecordRaw[];
2121
parent: RouteRecordRaw | undefined;
22+
name?:string
2223
}

packages/simple-router/src/router.tsx

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { START_LOCATION_NORMALIZED } from './types';
1010
import { RouterContext } from './hooks/useRouter';
1111
import { RouteContext } from './hooks/useRoute';
1212
import { warn } from './warning';
13+
import type { RouteRecordRaw } from './matcher/types'
1314

1415
const 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;

packages/simple-router/src/types/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,15 @@ export interface Router {
9090
getRouteByName: (name: string) => RouteRecordNormalized | undefined;
9191
resetRoute: () => void;
9292
getAllRouteNames: () => string[];
93+
back: () => void;
94+
forwardRef: () => void;
95+
go: (delta: number) => void;
96+
removeRoute:(name:string)=>void;
9397
}
94-
export interface HistoryStateArray extends Array<HistoryStateValue> {}
98+
export interface HistoryStateArray extends Array<HistoryStateValue> { }
99+
95100
export type HistoryStateValue = string | number | boolean | null | undefined | HistoryState | HistoryStateArray;
101+
96102
export interface HistoryState {
97103
[x: number]: HistoryStateValue;
98104
[x: string]: HistoryStateValue;

0 commit comments

Comments
 (0)