vue-router 源码和动态路由权限分配

): Matcher {

// 创建映射表

const { pathList, pathMap, nameMap } = createRouteMap(routes)

// 添加动态路由

function addRoutes(routes){…}

// 计算新路径

function match (

raw: RawLocation,

currentRoute?: Route,

redirectedFrom?: Location

): Route {…}

// … 后面的一些方法暂不展开

return {

match,

addRoutes

}

}

createMatcher 接受俩参数,分别是 routes,这个就是我们平时在 router.js 定义的路由表配置,然后还有一个参数是 router 他是 new vueRouter 返回的实例。

createRouteMap

下面这句代码是在创建一张 path-record,name-record 的映射表,我们将代码定位到 create-route-map.js 源码地址 (https://github.com/vuejs/vue-router/blob/dev/src/create-route-map.js)

export function createRouteMap (

routes: Array,

oldPathList?: Array,

oldPathMap?: Dictionary,

oldNameMap?: Dictionary

): {

pathList: Array,

pathMap: Dictionary,

nameMap: Dictionary

} {

// 记录所有的 path

const pathList: Array = oldPathList || []

// 记录 path-RouteRecord 的 Map

const pathMap: Dictionary = oldPathMap || Object.create(null)

// 记录 name-RouteRecord 的 Map

const nameMap: Dictionary = oldNameMap || Object.create(null)

// 遍历所有的 route 生成对应映射表

routes.forEach(route => {

addRouteRecord(pathList, pathMap, nameMap, route)

})

// 调整优先级

for (let i = 0, l = pathList.length; i < l; i++) {

if (pathList[i] === ‘*’) {

pathList.push(pathList.splice(i, 1)[0])

l–

i–

}

}

return {

pathList,

pathMap,

nameMap

}

}

createRouteMap 需要传入路由配置,支持传入旧路径数组和旧的 Map 这一步是为后面递归和 addRoutes 做好准备。首先用三个变量记录 path,pathMap,nameMap,接着我们来看 addRouteRecord 这个核心方法。这一块代码太多了,列举几个重要的步骤

// 解析路径

const pathToRegexpOptions: PathToRegexpOptions =

route.pathToRegexpOptions || {}

// 拼接路径

const normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict)

// 记录路由信息的关键对象,后续会依此建立映射表

const record: RouteRecord = {

path: normalizedPath,

regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),

// route 对应的组件

components: route.components || { default: route.component },

// 组件实例

instances: {},

name,

parent,

matchAs,

redirect: route.redirect,

beforeEnter: route.beforeEnter,

meta: route.meta || {},

props: route.props == null

? {}

: route.components

? route.props

: { default: route.props }

}

使用 recod 对象 记录路由配置有利于后续路径切换时计算出新路径,这里的 path 其实是通过传入父级 record 对象的path和当前 path 拼接出来的  。然后 regex 使用一个库将 path 解析为正则表达式。如果 route 有子节点就递归调用 addRouteRecord

// 如果有 children 递归调用 addRouteRecord

route.children.forEach(child => {

const childMatchAs = matchAs

? cleanPath(${matchAs}/${child.path})

: undefined

addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs)

})

最后映射两张表,并将 record·path 保存进 pathList,nameMap 逻辑相似就不列举了

if (!pathMap[record.path]) {

pathList.push(record.path)

pathMap[record.path] = record

}

废了这么大劲将 pathList 和 pathMap 和 nameMap 抽出来是为啥呢? 首先 pathList 是记录路由配置所有的 path,然后 pathMap 和 nameMap 方便我们传入 path 或者 name 快速定位到一个 record,然后辅助后续路径切换计算路由的。

addRoutes

这是在 vue2.2.0 之后新添加的 api ,或许很多情况路由并不是写死的,需要动态添加路由。有了前面的 createRouteMap 的基础上我们只需要传入 routes 即可,他就能在原基础上修改

function addRoutes (routes) {

createRouteMap(routes, pathList, pathMap, nameMap)

}

并且看到在 createMathcer 最后返回了这个方法,所以我们就可以使用这个方法

return {

match,

addRoutes

}

match

function match (

raw: RawLocation,

currentRoute?: Route,

redirectedFrom?: Location

): Route {

}

接下来就是 match 方法,它接收 3 个参数,其中 raw 是 RawLocation 类型,它可以是一个 url 字符串,也可以是一个 Location 对象;currentRoute 是 Route 类型,它表示当前的路径;redirectedFrom 和重定向相关。match 方法返回的是一个路径,它的作用是根据传入的 raw 和当前的路径 currentRoute 计算出一个新的路径并返回。至于他是如何计算出这条路径的,可以详细看一下如何计算出location的 normalizeLocation 方法和 _createRoute 方法。

小结
  • createMatcher: 根据路由的配置描述建立映射表,包括路径、名称到路由 record 的映射关系, 最

  • 12
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值