跨境库存Agent测评:开源产品无法动态备货?实在Agent以ISSUT技术重塑跨境电商供需链
2026/6/13 9:32:56
路由系统是应用中页面导航的核心。本文将介绍如何设计和封装一个完整的路由系统,包括:
通过本文,你将掌握如何构建一个健壮的路由系统。
完成本文后,你将能够:
| 模块 | 功能描述 | 技术要点 |
|---|---|---|
| 路由配置 | 管理路由表 | 路由映射、路径配置 |
| 导航守卫 | 路由跳转前后处理 | 权限验证、登录检查 |
| 参数传递 | 页面间数据传递 | URL参数、路由参数 |
| 路由拦截 | 拦截特定路由 | 登录拦截、权限控制 |
// router/RouterConfig.ets/** * 路由配置 */exportinterfaceRouteConfig{path:string;name:string;component:string;meta?:RouteMeta;}exportinterfaceRouteMeta{requiresAuth?:boolean;title?:string;keepAlive?:boolean;}/** * 路由表 */exportconstroutes:RouteConfig[]=[// 公共页面{path:'/',name:'Splash',component:'pages/Splash',meta:{keepAlive:false}},{path:'/login',name:'Login',component:'pages/Login',meta:{requiresAuth:false,title:'登录'}},// TabBar页面{path:'/home',name:'Home',component:'pages/Home',meta:{requiresAuth:false,title:'首页'}},{path:'/encyclopedia',name:'Encyclopedia',component:'pages/Encyclopedia',meta:{requiresAuth:false,title:'百科'}},{path:'/quiz',name:'Quiz',component:'pages/Quiz',meta:{requiresAuth:false,title:'测验'}},{path:'/profile',name:'Profile',component:'pages/Profile',meta:{requiresAuth:true,title:'我的'}},// 详情页面{path:'/detail/:id',name:'Detail',component:'pages/Detail',meta:{requiresAuth:false,title:'节气详情'}},{path:'/article/:id',name:'ArticleDetail',component:'pages/ArticleDetail',meta:{requiresAuth:false,title:'文章详情'}},// 设置页面{path:'/settings',name:'Settings',component:'pages/Settings',meta:{requiresAuth:true,title:'设置'}},{path:'/privacy',name:'Privacy',component:'pages/Privacy',meta:{requiresAuth:true,title:'隐私设置'}}];/** * 根据路径获取路由配置 */exportfunctiongetRouteByPath(path:string):RouteConfig|undefined{returnroutes.find(route=>{constroutePath=route.path;// 处理动态路由if(routePath.includes(':')){constregex=newRegExp('^'+routePath.replace(/:(\w+)/g,'([^/]+)')+'$');returnregex.test(path);}returnroutePath===path;});}/** * 根据名称获取路由配置 */exportfunctiongetRouteByName(name:string):RouteConfig|undefined{returnroutes.find(route=>route.name===name);}/** * 解析动态路由参数 */exportfunctionparseRouteParams(path:string,routePath:string):Record<string,string>{constparams:Record<string,string>={};constpathSegments=path.split('/').filter(Boolean);constrouteSegments=routePath.split('/').filter(Boolean);routeSegments.forEach((segment,index)=>{if(segment.startsWith(':')){constparamName=segment.slice(1);params[paramName]=pathSegments[index]||'';}});returnparams;}设计要点:
// router/RouterService.etsimportrouterfrom'@ohos.router';importpromptfrom'@ohos.prompt';import{routes,getRouteByPath,parseRouteParams,RouteConfig}from'./RouterConfig';/** * 路由服务 */classRouterService{privatestaticinstance:RouterService;// 路由栈privaterouteStack:string[]=[];/** * 获取单例实例 */staticgetInstance():RouterService{if(!RouterService.instance){RouterService.instance=newRouterService();}returnRouterService.instance;}/** * 导航到指定页面 */asyncpush(route:string|RouteConfig,params?:Record<string,any>):Promise<void>{letpath:string;letrouteConfig:RouteConfig|undefined;if(typeofroute==='string'){// 如果是字符串,可能是路径或名称routeConfig=getRouteByPath(route)||getRouteByName(route);path=routeConfig?.path||route;}else{path=route.path;routeConfig=route;}// 导航守卫检查constcanNavigate=awaitthis.beforeEach(path,routeConfig);if(!canNavigate){return;}try{// 构建URLleturl=`pages/${routeConfig?.component.split('/')[1]}`;// 处理动态路由参数if(routeConfig?.path.includes(':')&¶ms){letdynamicPath=routeConfig.path;Object.keys(params).forEach(key=>{dynamicPath=dynamicPath.replace(`:${key}`,params[key]);});}awaitrouter.pushUrl({url,params:params||{}});// 更新路由栈this.routeStack.push(path);// 导航后钩子this.afterEach(path,routeConfig);}catch(error){console.error('路由跳转失败:',error);prompt.showToast({message:'页面跳转失败'});}}/** * 返回上一页 */asyncback(options?:RouterBackOptions):Promise<void>{try{awaitrouter.back(options);this.routeStack.pop();}catch(error){console.error('返回失败:',error);}}/** * 返回到指定页面 */asyncbackTo(path:string):Promise<void>{constindex=this.routeStack.indexOf(path);if(index!==-1){conststeps=this.routeStack.length-index-1;for(leti=0;i<steps;i++){awaitrouter.back();}this.routeStack=this.routeStack.slice(0,index+1);}}/** * 替换当前页面 */asyncreplace(route:string|RouteConfig,params?:Record<string,any>):Promise<void>{leturl:string;if(typeofroute==='string'){constrouteConfig=getRouteByPath(route)||getRouteByName(route);url=`pages/${routeConfig?.component.split('/')[1]}`;}else{url=`pages/${route.component.split('/')[1]}`;}try{awaitrouter.replaceUrl({url,params:params||{}});}catch(error){console.error('路由替换失败:',error);}}/** * 返回到首页 */asyncbackToHome():Promise<void>{awaitrouter.back({url:'pages/Home'});this.routeStack=['/home'];}/** * 导航前守卫 */privateasyncbeforeEach(path:string,routeConfig?:RouteConfig):Promise<boolean>{// 检查是否需要登录if(routeConfig?.meta?.requiresAuth){constisLoggedIn=awaitthis.checkLogin();if(!isLoggedIn){prompt.showToast({message:'请先登录'});awaitrouter.pushUrl({url:'pages/Login'});returnfalse;}}// 检查权限if(routeConfig?.meta?.requiresAuth){consthasPermission=awaitthis.checkPermission(path);if(!hasPermission){prompt.showToast({message:'暂无权限访问'});returnfalse;}}returntrue;}/** * 导航后钩子 */privateafterEach(path:string,routeConfig?:RouteConfig):void{// 设置页面标题if(routeConfig?.meta?.title){this.setTitle(routeConfig.meta.title);}// 发送路由变更事件this.emitRouteChange(path);}/** * 检查登录状态 */privateasynccheckLogin():Promise<boolean>{// 从全局状态或本地存储检查登录状态consttoken=awaitthis.getToken();return!!token;}/** * 检查权限 */privateasynccheckPermission(path:string):Promise<boolean>{// 权限检查逻辑returntrue;}/** * 获取Token */privateasyncgetToken():Promise<string|null>{// 从本地存储获取Tokenreturnnull;}/** * 设置页面标题 */privatesetTitle(title:string):void{// 设置页面标题}/** * 发送路由变更事件 */privateemitRouteChange(path:string):void{// 触发路由变更事件}/** * 获取当前路由 */getCurrentRoute():string|undefined{returnthis.routeStack[this.routeStack.length-1];}/** * 获取路由栈 */getRouteStack():string[]{return[...this.routeStack];}}interfaceRouterBackOptions{url?:string;params?:Record<string,any>;}/** * 全局路由服务实例 */exportconstrouterService=RouterService.getInstance();/** * 便捷导航方法 */exportconstnavigateTo=(route:string,params?:Record<string,any>)=>{returnrouterService.push(route,params);};exportconstnavigateBack=(options?:RouterBackOptions)=>{returnrouterService.back(options);};exportconstnavigateReplace=(route:string,params?:Record<string,any>)=>{returnrouterService.replace(route,params);};设计要点:
// 在组件中使用路由服务import{routerService,navigateTo}from'../router/RouterService';@Entry@Componentstruct HomePage{goToDetail(id:string){// 使用路由服务导航routerService.push('/detail/:id',{id});// 或者使用便捷方法// navigateTo('Detail', { id });}goToLogin(){routerService.push('Login');}goBack(){routerService.back();}build(){Column({space:16}){Button('查看详情').onClick(()=>this.goToDetail('lichun'))Button('去登录').onClick(()=>this.goToLogin())Button('返回').onClick(()=>this.goBack())}.width('100%').height('100%').padding(16).justifyContent(FlexAlign.Center)}}设计要点:
本文完成了路由系统的设计与封装:
1. 路由配置
2. 路由服务
3. 导航守卫
路由系统已经完成!在下一篇文章中,我们将学习: