您的位置:首页 > 娱乐 > 明星 > 宁波妇科中医_网络在线客服系统_百度关键词代做排名_开封搜索引擎优化

宁波妇科中医_网络在线客服系统_百度关键词代做排名_开封搜索引擎优化

2025/4/9 4:53:36 来源:https://blog.csdn.net/inksnowHL/article/details/146503921  浏览:    关键词:宁波妇科中医_网络在线客服系统_百度关键词代做排名_开封搜索引擎优化
宁波妇科中医_网络在线客服系统_百度关键词代做排名_开封搜索引擎优化

个人博客原文地址

此文章并不适合初级前端来看,它是抽象的架构设计,需要一定的TS基础和抽象思维,若带着思考的读完本文章相信会让你感到充实

当然你也可以复制,然后在自己项目中去实现它,然后用起来

只要你是在写前端页面,那么好的路由导航无非就两种

  • 编程式导航
  • 约定式导航

一种是你来控制导航方向和所有页面的导航路径,另一种是根据目录结构来自动生成导航.
而编程式导航,也许我们也应该抽象出来,统一下,让我们切换vue、react亦或者其他东西都不必再需要多余成本,让路由中需要加入一些业务逻辑变得方便,让路由的权限控制变得简单,让路由的历史记录管理变得可控。
所以,便有了这个设计
我在设计这个架构时,最核心的理念是抽象解耦。我希望路由导航的逻辑能够独立于具体的框架存在,这样一套代码就能适配各种环境,既减少重复开发,又方便未来的扩展。同时使用中间件,让路由导航的逻辑更加模块化,可插拔,可控。

这里面都有什么?

核心模块

  1. 导航器(INavigator)
    导航器是这个设计的导航口,通过这个去调用跳转,这并没有破坏我们使用vue-router或者react-router的习惯

  2. 路由解析器(IRouteResolver)
    路由解析器从路由信息中解析出来我原始的路由配置对象。对于页面的导航配置相关细则,就在这里面了。

  3. 中间件与导航管道(NavigationPipeline)
    ::: tip 提示
    这个部分是唯一特殊一点的部分,管道只是为了让中间件更好的用起来,所以这里我完善了一部分实现,你可以有你自己的设计,只要让中间件的思想和逻辑存在且可用
    :::
    我借鉴了管道模式,且是阻塞式的管道模式。在导航前,用中间件去处理每个路由需要处理的事情,每个中间件只负责一件事,比如路由守卫检查权限、历史管理记录路径等。这样的模块化设计可以随时插拔不同逻辑处理,想加个新需求?插个中间件就搞定,维护起来也顺手。

  4. 历史管理器(IHistoryManager)
    主动对历史记录进行管理和追踪,可控的方式去进行历史管理。这里推荐用 History API去实现,达到和浏览器同步历史记录栈。

  5. 适配器(AbstractRouterAdapter)
    适配器,就是用不同框架来对接的接口。我定义了一个抽象类 AbstractRouterAdapter,里面封装了通用的接口和方法。只要为特定框架实现一个适配器,我的整个路由系统就能无缝接入,无论是 React、Vue 还是 Angular,你可以不必再重写路由的各种逻辑,直接复用

宏观的整体依赖关系

这里我严格遵循了低层策略依赖高层策略,一定要单向,这样才能保证系统的稳定性和可维护性。

uml图

涉及的设计模式

  • 适配器模式和工厂模式让我实现了跨框架复用和实例创建的灵活性。
  • 管道模式和观察者模式增强了导航过程的模块化和可控性。
  • 策略模式则让导航行为更加动态和多样化。

对于设计模式,善用可以增加可读性和可扩展性,否则就是破坏代码简单性。

设计的TS抽象源码

这里只是一个设计的抽象模型,你可以根据这个模型去实现你的路由导航系统
无视框架,甚至无视语言,只要你能实现这个模型,你就可以在任何地方使用这个路由系统。
其他平台不是ts语言怎么办?AI会出手,助你转译

如果你不想先看这些源码,而是想看看图像,它们在下面

// router_domain.ts
/*** @description: 路由携带数据* @return {*}*/
export interface NavigationOptions {params?: Record<string, string>;query?: Record<string, string>;hash?: string;
}
/*** @description: 跳转类型* @return {*}*/
export enum NavigationType {push = 'push',replace = 'replace',back = 'back',forward = 'forward',
}/*** @description: 路由守卫,返回一个真正要跳转的路由* @return {*} 返回一个新的跳转路径,或者什么也不返回,按原计划跳转*/
export interface RouteGuard {(context: NavigationContext): NavigationInstruction|void | Promise<NavigationInstruction|void>;
}/*** @description: 路由进入前的钩子* @return {*}*/
export interface RouterBefore {(context: NavigationContext): void | Promise<void>;
}/*** @description: 路由离开前的钩子* @return {*}*/
export interface RouterLeave {(context: NavigationContext): void | Promise<void>;
}/*** @description: 路由上下文* @return {*}*/
export class NavigationContext {constructor(public instruction: NavigationInstruction,public prevInstruction: NavigationInstruction|null,public nextInstruction: NavigationInstruction|null,public currentRoute: ResolvedRoute,) {}
}/*** @description: 路由指令* @return {*}*/
export class NavigationInstruction {constructor(public type: NavigationType,public target: string,public options: NavigationOptions,public timestamp: number) {}
}/*** @description: 路由解析* @return {*}*/
export class ResolvedRoute {constructor(public path: string,public component: any,public guards: RouteGuard[] = [],public enterHook: RouterBefore[] = [],public leaveHook: RouterLeave[] = [],public children: ResolvedRoute[] = [],public metadata: Map<string, any> = new Map()) {}
}
// router_core.ts
import {NavigationContext,NavigationInstruction,NavigationOptions,NavigationType,ResolvedRoute,
} from "./router_domain";/*** @description:导航器,使用有两种方式进行编程式路由导航* @return {*}*/
export interface INavigator {push(target: string, options: NavigationOptions): Promise<void>;replace(target: string, options: NavigationOptions): Promise<void>;back(): Promise<void>;forward(): Promise<void>;
}/*** @description: 路由解析器,用于解析路由实际对象* @return {*}*/
export interface IRouteResolver {resolve(path: string): Promise<ResolvedRoute>;
}/*** @description: 中间件逻辑,用于处理路由跳转前的随时可插拔处理* @return {*}*/
export interface IMiddleware {process(context: NavigationContext, next: () => Promise<void>): Promise<void>;
}/*** @design: 建议实现为单例模式* @description: 历史管理器,用于管理路由历史记录,用于可监控式路由路径* @return {*}*/
export interface IHistoryManager {push(entry: NavigationInstruction): void;replace(entry: NavigationInstruction): void;back(): void;forward(): void;getAllHistory(): NavigationInstruction[];clear(): void;
}/*** @description: 路由数据,用于存储全部路由信息* @return {*}*/
export interface IRoute {routes: ResolvedRoute[];routeMap: Map<string, ResolvedRoute>;createRouteMap(): void;addRoute(route: ResolvedRoute): void;
}
// router_pipeline.ts
import { IHistoryManager, IMiddleware } from "./router_core";
import { NavigationContext } from "./router_domain";/*** @description: 管道设计,当前这个是阻塞式的管道设计,依次处理中间件* @return {*}*/
export class NavigationPipeline {middlewares: IMiddleware[] = [];errorHandler?: (error: Error, context: NavigationContext) => void;async pipe(context: NavigationContext): Promise<void> {let index = 0;const next = async () => {if (index < this.middlewares.length) {const middleware = this.middlewares[index++];await middleware.process(context, next);}};await next();}addMiddleware(middleware: IMiddleware): void {this.middlewares.push(middleware);}onError(handler: (error: Error, context: NavigationContext) => void): void {this.errorHandler = handler;}
}/*** @description: 路由守卫中间件* @return {*}*/
export class GuardMiddleware implements IMiddleware {async process(context: NavigationContext,next: () => Promise<void>): Promise<void> {const route = context.currentRoute;for (const guard of route.guards) {const result = await guard(context);//   若得到了新的跳转路径,则跳转到新的路径if (result) {context.instruction = result;break;}}await next();}
}export class HistoryMiddleware implements IMiddleware {histroyManager: IHistoryManager;constructor(histroyManager: IHistoryManager) {this.histroyManager = histroyManager;}async process(context: NavigationContext,next: () => Promise<void>): Promise<void> {const instruction = context.instruction;const type = instruction.type;this.histroyManager[type](instruction);next();}
}
// router_Adapter
import { INavigator, IRouteResolver, IHistoryManager, IRoute } from "./router_core"
import { NavigationPipeline } from "./router_pipeline"export abstract class AbstractRouterAdapter {navigator: INavigatorresolver: IRouteResolverhistory: IHistoryManagerroute:IRoutepipeline: NavigationPipelineinitialize(route:IRoute,pipeline:NavigationPipeline): void{this.route = routethis.pipeline = pipelinethis.navigator = this.createNavigator()this.resolver = this.createResolver()this.history = this.createHistory()}abstract createNavigator(): INavigatorabstract createResolver(): IRouteResolverabstract createHistory(): IHistoryManagerabstract errorHandler():void
}

图像也许会帮你更好的理解

流程图

流程图

细节的类图

以下uml图,可以帮你快速的理解我这里的依赖关系,他是单向的,高层策略和低层策略是很明显的。

你可以右键下面这个图,在新的标签页中打开,这样可以放大和拖动的查看

类图

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com