关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

基于 vue-antd-admin 开发项目后的几点感想(二):异步路由和菜单

发布时间:2023-06-26 20:59:56

前言


上一篇 讲了使用 vue-antd-admin 开发中台项目后的一些感想,并没有提到其动态路由的配置,主要是因为当时觉得其文档写的比较详细了,而且当时并没有遇到什么坑,没想到今天接了一个需求,需要开发一套消息系统,其中有一个显示全部消息的页面,我按照官方文档中的方法配置了页面路由后,发现和我想要的效果不同,其直接全屏显示了,而我需要的是显示在侧边栏菜单的右侧内容部分,于是仔细看了文档和源码后,花了亿点点时间解决了这个需求,并且产出了本篇文章。


路由与菜单


我长话短说,基本的使用一定要看官方文档,概述起来就是说,vue-antd-admin 项目也是完全依赖 vue-router 并使用其配置规则,其提供了同步、异步两种路由方案:

同步的非常简单,就是我们熟悉的vue-router 的配置, 示例代码可以看这个 src/router/config.js就不讲了;

关键是异步,首先需要本地配置路由的map 文件,也就是把所有的完整路由拆分成单个的路由配置进行注册, 文件在这里 /router/async/router.map.js

然后根据接口返回的路由配置与map 文件结合生成最终的路由,接口返回的路由格式如下


[{  router: 'root', //匹配 router.map.js 中注册名 registerName = root 的路由  children: [ //root 路由的子路由配置  {  router: 'dashboard', //匹配 router.map.js 中注册名 registerName = dashboard 的路由  children: ['workplace', 'analysis'], //dashboard 路由的子路由配置,依次匹配 registerName 为 workplace 和 analysis 的路由  },  {  router: 'form', //匹配 router.map.js 中注册名 registerName = form 的路由  children: [ //form 路由的子路由配置  'basicForm', //匹配 router.map.js 中注册名 registerName = basicForm 的路由  'stepForm', //匹配 router.map.js 中注册名 registerName = stepForm 的路由  {  router: 'advanceForm', //匹配 router.map.js 中注册名 registerName = advanceForm 的路由  path: 'advance' //重写 advanceForm 路由的 path 属性  }  ]  },  {  router: 'basicForm', //匹配 router.map.js 中注册名 registerName = basicForm 的路由  name: '验权表单', //重写 basicForm 路由的 name 属性  icon: 'file-excel', //重写 basicForm 路由的 icon 属性  authority: 'form' //重写 basicForm 路由的 authority 属性  }  ] }]

   


重点来了,异步路由是不能覆盖所有的路由的,比如404、login 之类的页面是不需要配置到接口权限里的,所有我们需要一个基础路由配置文件,里面注册的路由都可以merge 到最终的路由配置中。

文件地址在这里 /router/async/config.async.js

官方文档中基础路由的配置使用方法如下:


const routesConfig = [  'login', //匹配 router.map.js 中注册的 registerName = login 的路由  'root', //匹配 router.map.js 中注册的 registerName = root 的路由  {  router: 'exp404', //匹配 router.map.js 中注册的 registerName = exp404 的路由  path: '*', //重写 exp404 路由的 path 属性  name: '404' //重写 exp404 路由的 name 属性  },  {  router: 'exp403', //匹配 router.map.js 中注册的 registerName = exp403 的路由  path: '/403', //重写 exp403 路由的 path 属性  name: '403' //重写 exp403 路由的 name 属性  } ]

   


如果按照此方法配置,最终的路由文件大概是这样子



可以看到 消息中心是和跟路由平级的,此时的效果是这样的



看来我需要把 notification 路由给添加到首页下的children 属性里,其才会在侧边栏生成新的菜单,我修改一下配置方法试试

然后发现,/首页下的children 中并没有这个路由,也就是说其并没有别merge 到一起;问题出在 路由merge 函数里,这个函数在这里 src/utils/routerUtil.jsloadRoutes 中的


因涉及一些执行语句,禁止写入,请联系客服获取


那么看下它是怎么定义的


因涉及一些执行语句,禁止写入,请联系客服获取


可以看到,其是一个浅拷贝函数,同名属性会被覆盖掉,额看来我需要改造一下写一个深度拷贝函数,突然我发现 mergeRoutes 函数下紧接着就有一个定义好的 深度合并路由函数!


因涉及一些执行语句,禁止写入,请联系客服获取


可以看到其是用深度优先的递归方式来进行merge 操作的; 现在我把 mergeRoutes 替换为 deepMergeRoutes 尝试下发现真的成功了!



虽然在官方文档中并没有看到这个函数的身影,但是作者显然考虑到了这种需求,这样,异步路由的方案使用起来就更方便了。

对了,官方还在 routes 的元数据属性 meta 中注入了三个属性 icon、invisible 和 page,其中 invisible 将控制其是否显示在侧边栏菜单中,这个很有用。


总结


今天通过一个具体的需求探究,介绍了 vue-antd-admin 的动态路由方案,本来我还觉得它不太好用,今天无意中发现了 deepMergeRoutes 函数,通过它本地基础路由的配置方便很多,现在看来这个异步动态路由方案还是挺不错的,点赞。


/template/Home/leiyu/PC/Static