前言自从前端框架流行以来,路由这个词在前端越来越流行,几乎是所有前端框架的核心功能点。与后端不同,前端路由往往需要表达更多的业务功能,比如与菜单耦合,与标题耦合,与“面包屑”耦合等,因此很少有开箱即用的完整解决方案,更多或更少需要重新处理。一、UmiJS简介一个优秀的框架可以缩短90%以上的无效开发时间。Ant的UmiJS是我见过最优雅的React应用框架,也可以直接说是最优雅的前端解决方案(欢迎挑战),这个系列之上的应用会逐步扩展。本文重点介绍“路由”,后续系列的其余部分将继续深入。2.需求概述在搬代码之前,我们先想象一下这次要实现什么功能:路由需要耦合菜单,需要自动向下填充菜单的空节点;模板的概念必须始终体现在路由中,即不同的路由允许使用未使用的模板组件;模板与页面的关系完全交给路由组合,不再体现在组件中;需要实现从路由中获取当前页面轨迹的功能,即“面包屑”;从路由中获取页面标题;以上各点的作用并不复杂。如果不追求极致,其实默认的常规路由基本可以满足需求(具体可以参考官方文档,这里不再展开)。3、打开代码3.1菜单先从菜单开始,下面应该是最简洁的目录结构:constmenu=[{name:'parentnode',path:'parent',children:[{name:'childpage',路径:'孩子'}]}];使用递归完成子路径:constreg=/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;constformatMenu=(data,parentPath=`${define.BASE_PATH}/`)=>{返回数据。map((item)=>{let{path}=item;if(!reg.test(path)){path=parentPath+item.path;}constresult={...item,path};if(item.children){result.children=formatMenu(item.children,`${parentPath}${item.path}/`);}returnresult;});}菜单的子节点是真正的页面,所以如果当前路径是父节点,我们期望的是自动跳转到父节点写入的第一个或特定页面:constredirectData=[];constformatRedirect=item=>{if(item&&item.children){if(item.children[0]&&item.children[0].path){重定向Data.push({路径:`${item.path}`,重定向:`${item.children[0].path}`});item.children.forEach(children=>{formatRedirect(children);});}}};constgetRedirectData=(menuData)=>{menuData.forEach(formatRedirect);返回重定向数据};3.2路由组装然后自动跳转路径组装成路由节点:constroutes=[...redirect,{path:define.BASE_PATH,component:'../layouts/BasicLayout',routes:[{path:`${define.BASE_PATH}/parent`,routes:[{title:'subpage',path:'child',component:'./parent/child',}],},{component:'./404',}]}];路由配置需要在末尾注入配置文件.umirc.js:import{plugins}from'./config/plugins';import{routes}from'./config/routes';exportdefault{plugins,routes}3.3模板页面import{Layout}from'antd';importReact,{PureComponent,Fragment}from'react';import{ContainerQuery}from'react-container-query';从'react-document-title'导入文档标题;从'@/utils/layout'导入{查询};从'./Footer'导入页脚;从'./MenuContext'导入上下文;const{内容}=Layout;classBasicLayoutextendsPureComponent{render(){const{children,location:{pathname}}=this.props;constlayout=(
