写在前面
vue-router使用 path-to-regexp作为路径匹配引擎,所以支持很多高级的匹配模式,例如:可选的动态路径参数、匹配零个或多个、一个或多个,甚至是自定义正则匹配。查看它的文档学习高阶的路径匹配,还有这个例子展示vue-router怎么使用这类匹配。——引用自官网
附上AntDesignVuePro这个开源项目中的路由配置示例,该配置比较符合路由非常多的复杂项目的开发实际,所以拿来当个示例,后面讲到的内容,大多参考这里,有兴趣的朋友可以好好研究下。
所谓站在巨人的肩膀上,VueRouter使用这个模块作为路径匹配引擎。path属性作为路由核心属性之一,我们有必要仔细了解一下其匹配机制,以便我们在路由设计上更加得心应手。
本文抛砖引玉,详细用法请自行参考相关链接,文章中如有描述不清楚的地方,欢迎评论指出。
参数限定
利用path-to-regexp提供的能力,可以很好的限制路径,做到精准匹配。
const RouterView = { render: h => h('router-view') }
const typeLimit = 'image|text|video|audio'
const route = {
path: 'package',
component: RouterView,
children: [
{
// 通过正则限定type为素材类型,id是数字。若不满足则不会命中
path: `:type(${typeLimit})/:id(\\d+)`, // ①
meta: { name: '素材包详情' },
component: /*对应组件*/,
},
{
path: `:type(${typeLimit})`, // ②
meta: { name: '素材包列表' },
component: /*对应组件*/,
},
]
}
// 命中示例
const hits = [
'package/text', // 命中②,文本素材包列表
'package/text/1316 ', // 命中①,素材包1316的详情页面
'package/text/abc', // 未命中,因为①中:id参数(abc)不是数字
'package/material', // 未命中,因为②中:type参数(material)不属于素材类型
]
从上面的示例中可以看出,在经过正则限定之后,但凡匹配到了对应的路由,那么其参数一定在预料之中,换句话说,package/:type(${typeLimit})路径中拿到的$route.params.type一定是四种类型之一。
通过不同的参数限定,我们还可以实现一个路径,多个路由的效果,例如material/:type(${typeLimit})、material/edit、material/create,这都是常规操作了。
而在以往配置中我们基本上一个路径对应一个页面,package/:type路径只要符合基本结构就能匹配上,其中的type参数可能并不是我们想要的类型,如package/material,但由于结构符合条件,仍会匹配上,这显然不符合预期,因为type参数类型错误,如果是常规匹配,这将可能会造成一些异常。但如果是高级匹配,则不用担心。
同时需要注意VueRouter的路由匹配的优先级——越靠前的路由优先级越高,如果一个路径同时符合多条路由,则会优先匹配靠前的路由。当然,实际使用中慎用,因为可能会造成bug,最好通过参数限定的方式使得路由变得相对唯一。
倘若我们配置了404通配路由,那么未匹配的路由均会指向404页面,整个过程合情合理。
从此世上再无多余的路由...
路由组件透传
细心的伙伴可能已经注意到了,在上面的例子中,用到了一个非常简单的组件RouterView。受AntDesignVuePro这个开源项目的启发,这个组件虽然简单,却很巧妙和实用。这样处理,使得子路由不必局限在同一个父组件下,适用于子路由逻辑独立且不共享布局的场景。
还是用上面提到的三个路由material/:type(${typeLimit})、material/edit、material/create来举例。其中edit和create是同一个页面的不同状态,但material/:type(${typeLimit})代表了对应的素材列表,edit或create的素材将会展示在素材列表中。很明显,编辑页面的逻辑和布局不同于展示页面,但他们又有着一些联系,很适合写在一起集中管理。
其他
写了这么久项目,最常用的东西,自己竟没搞懂。笔者也是在做需求的过程中发现,项目路由管理非常混乱,并且命名夹杂大小写、下划线等符号。
再加上项目隶属于微前端子应用,路径本身已经嵌套了一个非常长的前缀,如果项目自身的路劲过长,雪上加霜,那真的不要太酸爽。
为了简化路径,不得不做出改变,而我也是在解决问题的过程中,仔仔细细查找了官方文档才发现这个宝藏用法,分享出来希望能帮助大家规范、优雅地配置自己项目的路由。