# 路由映射表与动态路由
# createMatcher
我们在使用 Vue-Router 的时候,需要创建 VueRouter 实例,并传入配置。之后再将这个 VueRouter 实例传入 Vue 根实例中。
const router = new VueRouter({
mode:'hash',
base:'',
routes:[]
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
在创建 VueRouter 时,比较重要的一个属性就是 matcher(匹配器),通过 createMatcher 来创建的。
this.app = null
this.apps = []
this.options = options
this.beforeHooks = []
this.resolveHooks = []
this.afterHooks = []
this.matcher = createMatcher(options.routes || [], this)
createMatcher :
// 创建匹配器
import createRouteMap from "./create-router-map";
export default function createMatcher(routes) {
// 创建映射表
let { pathMap } = createRouteMap(routes)
/**
*
* @param {Array} routes 动态添加多个路由
*/
function addRoutes(routes) {
createRouteMap(routes, pathMap)
}
/**
*
* @param {object} route 动态添加一个路由
*/
function addRoute(route) {
createRouteMap([route], pathMap)
}
/**
* 根据路由路径,返回对应的路由对象
* @param {string} url 路由的路径
* @returns object
*/
function match(url) {
return pathMap[url]
}
return {
addRoutes,
addRoute,
match
}
}
# 路由映射表
在创建匹配器时,第一步也是最重要的一步,就是创建路由映射表。在我们定义路由时,传入的是树状的数组,但是树状数组十分难操作,无论是后面动态添加路由,还是根据地址匹配路由,都很浪费性能。所以,Vue-Router 会将传入的数组扁平化,将路由路径作为映射表的 key,对应的路由对象作为映射表的 value。
// 创建路由映射表
/**
* 构建路由信息映射表
* @param {Array} routes 路由信息
* @param {Array} pathMap 已有的路由映射表,可选
*/
export default function createRouteMap(routes, pathMap = {}) {
routes.forEach(route => {
addRouteRecord(route, pathMap)
})
return { pathMap }
}
/**
*
* @param {object} route 具体某个路由信息对象
* @param {object} pathMap 映射表
* @param {object} parentRecord 父路由信息对象
*/
function addRouteRecord(route, pathMap, parentRecord) {
let path = route.path
// 拼接路径
if (parentRecord?.path) {
path = parentRecord.path === '/' ? `/${route.path}` : `${parentRecord.path}/${route.path}`
}
let record = {
path,
component: route.component,
props: route.props,
meta: route.meta,
name: route.name
}
// 路径 对应 路由信息
// 如果路径相同,后面的路由会覆盖前面的路由
pathMap[path] = record
// 递归处理子节点
if (route.children) {
route.children.forEach(cld => {
addRouteRecord(cld, pathMap, record)
})
}
}
# 动态路由
在做到权限管理类的项目时,时常需要用到动态路由。在某些情况下,我们需要动态的向路由表中添加路由,这就用到了 Vue-Router 中的 addRoutes / addRoute API 。
/**
* 动态添加多个路由
* @param {Array} routes 要动态添加多个路由数组
*/
function addRoutes(routes) {
createRouteMap(routes, pathMap)
}
/**
* 动态添加一个路由
* @param {object} route 要动态添加一个路由
*/
function addRoute(route) {
createRouteMap([route], pathMap)
}
/**
* 根据路由路径,返回对应的路由对象
* @param {string} url 路由的路径
* @returns object
*/
function match(url) {
return pathMap[url]
}
可以看到, addRoutes / addRoute 的底层其实就是将动态添加的路由以及当前已有的路由映射表 pathMap 传入 createRouteMap 函数,进而将新传入的路由解析到已有的路由映射表中。