vue-router 源码和动态路由权限分配,前端开发必备

})

// 调整优先级

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 的映射关系, 最重要的就是 createRouteMap 这个方法,这里也是动态路由匹配和嵌套路由的原理。

  • addRoutes: 动态添加路由配置

  • match: 根据传入的 raw 和当前的路径 currentRoute 计算出一个新的路径并返回。

路由模式

vue-router 支持三种路由模式(mode):hashhistoryabstract,其中 abstract 是在非浏览器环境下使用的路由模式 源码地址 (https://github.com/vuejs/vue-router/blob/dev/src/index.js)。

这一部分在前面初始化 vueRouter 对象时提到过,首先拿到配置项的模式,然后根据当前传入的配置判断当前浏览器是否支持这种模式,默认 IE9 以下会降级为 hash。然后根据不同的模式去初始化不同的 history 实例。

// 一般分两种模式 hash 和 history 路由 第三种是抽象模式不常用

let mode = options.mode || ‘hash’

// 判断当前传入的配置是否能使用 history 模式

this.fallback = mode === ‘history’ && !supportsPushState && options.fallback !== false

// 降级处理

if (this.fallback) {

mode = ‘hash’

}

if (!inBrowser) {

mode = ‘abstract’

}

this.mode = mode

// 根据模式实例化不同的 history history 对象会对路由进行管理 继承于 history class

switch (mode) {

case ‘history’:

this.history = new HTML5History(this

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值