Skip to content

Commit

Permalink
feat(packages): add remove route & If the route to be jumped is the c…
Browse files Browse the repository at this point in the history
…urrent route, no jump occurs
  • Loading branch information
Ohh-889 committed Aug 31, 2024
1 parent f1dcd68 commit a75c25e
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 17 deletions.
6 changes: 4 additions & 2 deletions packages/simple-router/src/matcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class CreateRouterMatcher {
const parentPath = parent.record.path as string;
const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/';
normalizedRecord.path = parent.record.path + (path && connectingSlash + path);

}

// create the object beforehand, so it can be passed to children
Expand Down Expand Up @@ -190,6 +191,7 @@ class CreateRouterMatcher {
path,
hash: location.hash,
component,
redirect: matcher.record.redirect,
matched,
query,
meta: mergeMetaFields(matched)
Expand All @@ -202,8 +204,7 @@ class CreateRouterMatcher {
* @returns An array of route names.
*/
getAllRouteNames() {
const names = Array.from(this.matcherMap.keys());
return names;
return Array.from(this.matcherMap.keys())
}

/**
Expand All @@ -212,6 +213,7 @@ class CreateRouterMatcher {
* @param matcher - The matcher object to insert.
*/
insertMatcher(matcher: RouteRecordRaw) {

if (matcher.record.path === '*') {
this.matchers.unshift(matcher);
} else {
Expand Down
3 changes: 2 additions & 1 deletion packages/simple-router/src/matcher/pathMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export function createRouteRecordMatcher(record: RouteRecordNormalized, parent?:
record,
parent,
// these needs to be populated by the parent
children: []
children: [],
name:record.name
};

if (parent) {
Expand Down
8 changes: 6 additions & 2 deletions packages/simple-router/src/matcher/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ export function generatePath(pathTemplate: string, params: { [key: string]: stri
* @returns the normalized version
*/
export function normalizeRouteRecord(record: ElegantConstRoute): RouteRecordNormalized {

return {
redirect: record.redirect,
redirect: record.redirect||record.children&&record.children[0].path,
path: record.path || '',
name: record.name,
meta: record.meta || {},
children: record.children || [],
children: record.children?.map(child => {
child.redirect=child.redirect||child.children&&child.children[0].path
return child
}) || [],
component: record.component
};
}
Expand Down
1 change: 1 addition & 0 deletions packages/simple-router/src/matcher/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export interface RouteRecordRaw {
record: RouteRecordNormalized;
children: RouteRecordRaw[];
parent: RouteRecordRaw | undefined;
name?:string
}
86 changes: 75 additions & 11 deletions packages/simple-router/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { START_LOCATION_NORMALIZED } from './types';
import { RouterContext } from './hooks/useRouter';
import { RouteContext } from './hooks/useRoute';
import { warn } from './warning';
import type { RouteRecordRaw } from './matcher/types'

const historyCreatorMap: Record<
'hash' | 'history' | 'memory',
Expand Down Expand Up @@ -89,9 +90,35 @@ class CreateRouter {
});

// Update react-router's routes
this.#changeRoutes()
}

#changeRoutes() {
this.reactRouter._internalSetRoutes([...this.initReactRoutes, ...this.reactRoutes]);
}

removeRoute(name: string) {
const matched = this.matcher.getRecordMatcher(name)
if (!matched) return
if (matched.parent) {

const parentNames = findParentNames(matched.parent)
let routes = this.reactRoutes

parentNames.forEach(name => {
const finalRoute = routes.find(route => route.id === name)
if (finalRoute && finalRoute.children) routes = finalRoute.children
})
removeElement(routes, matched.name)

} else {
this.reactRoutes = this.reactRoutes.filter(route => route.id !== matched.record.name)
}
this.#changeRoutes()
this.matcher.removeRoute(name);

}

#onBeforeRouteChange = (
{ currentLocation, nextLocation }: Parameters<BlockerFunction>[0],
beforeEach: RouterOptions['beforeEach'],
Expand All @@ -112,18 +139,25 @@ class CreateRouter {

const to = this.resolve(nextLocation);

const matchedRoutes = to.matched;
const nextRoute = matchedRoutes[matchedRoutes.length - 1];
if (to.redirect) {
if (to.redirect.startsWith('/')) {
if (to.redirect === this.currentRoute.fullPath) {
return true
}
} else {
const finalRoute = to.matched[to.matched.length - 1]

const finalPath = getFullPath(nextRoute);

if (finalPath === this.currentRoute.path || matchedRoutes[0]?.redirect === this.currentRoute.path) {
return true;
const finalPath = getFullPath(finalRoute)

if (finalPath === this.currentRoute.fullPath) return true
}
}

return beforeEach(to, this.currentRoute, this.#next);
};


#next(param?: boolean | string | Location | RouteLocationNamedRaw) {
if (!param) return false;
if (typeof param === 'string') {
Expand Down Expand Up @@ -224,7 +258,7 @@ class CreateRouter {
* @param key Route key
*/
getRouteMetaByKey(key: string) {
return this.getRoutes().find(route => route.name === key)?.meta || null;
return this.getRoutes().find(route => route.name === key)?.meta;
}

#afterRouteChange = (state: RouterState, afterEach: RouterOptions['afterEach']) => {
Expand Down Expand Up @@ -253,7 +287,7 @@ class CreateRouter {
* @param name - The name of the route.
* @returns The route record or false if not found.
*/
getRouteByName(name: string): RouteRecordNormalized | undefined {
getRouteByName(name: string) {
return this.matcher.getRecordMatcher(name)?.record;
}

Expand Down Expand Up @@ -285,13 +319,43 @@ function cleanParams(params: Record<string, any> | undefined): Record<string, an
return Object.fromEntries(Object.entries(params).filter(([_, value]) => value !== null));
}

function getFullPath(route: RouteRecordNormalized | ElegantConstRoute): string {




function findParentNames(matched: RouteRecordRaw | undefined): (string | undefined)[] {
const parentNames: (string | undefined)[] = []

function helper(current: RouteRecordRaw | undefined) {
if (current?.parent) {
helper(current.parent)
}
parentNames.push(current?.name)
}

helper(matched)

return parentNames
}


function removeElement(arr: RouteObject[], name: string | undefined) {
const index = arr.findIndex(route => route.id === name);
if (index !== -1) {
arr.splice(index, 1);
}
return arr;
}


function getFullPath(route: RouteRecordNormalized | ElegantConstRoute ): string {
// 如果当前 route 存在并且有 children
if (route && route.children && route.children.length > 0) {
if (route && route.redirect && route.children && route.children.length > 0) {
// 获取第一个子路由
const firstChild = route.children[0];
const firstChild = route.children.find(child => child.path === route.redirect)
// 递归调用,继续拼接子路由的 path
return `${route.path}/${getFullPath(firstChild)}`;
if (firstChild)
return `${route.path}/${getFullPath(firstChild)}`;
}
// 如果没有 children,返回当前 route 的 path
return route.path;
Expand Down
8 changes: 7 additions & 1 deletion packages/simple-router/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,15 @@ export interface Router {
getRouteByName: (name: string) => RouteRecordNormalized | undefined;
resetRoute: () => void;
getAllRouteNames: () => string[];
back: () => void;
forwardRef: () => void;
go: (delta: number) => void;
removeRoute:(name:string)=>void;
}
export interface HistoryStateArray extends Array<HistoryStateValue> {}
export interface HistoryStateArray extends Array<HistoryStateValue> { }

export type HistoryStateValue = string | number | boolean | null | undefined | HistoryState | HistoryStateArray;

export interface HistoryState {
[x: number]: HistoryStateValue;
[x: string]: HistoryStateValue;
Expand Down

0 comments on commit a75c25e

Please # to comment.