前言

【vue-router源码】系列文章将带你从0开始理解vue-router的具体实现。该系列文章源码参考vue-router v4.0.15
源码地址:https://github.com/vuejs/router
浏览该文章的前提是你最好理解vue-router的根本应用,如果你没有应用过的话,可通过vue-router官网学习下。

该篇文章将剖析router.addRoute的实现。

应用

当应用addRoute增加路由时,如果第一个参数为路由name,那么会增加一个嵌套路由;否则增加的是个非嵌套路由。

// 增加非嵌套路由router.addRoute({ name: 'admin', path: '/admin', component: Admin })// 增加嵌套路由router.addRoute('admin', { path: 'settings', component: AdminSettings })

以上代码等同于:

router.addRoute({  name: 'admin',  path: '/admin',  component: Admin,  children: [{ path: 'settings', component: AdminSettings }],})

addRoute

function addRoute(    parentOrRoute: RouteRecordName | RouteRecordRaw,    route?: RouteRecordRaw  ) {    let parent: Parameters<typeof matcher['addRoute']>[1] | undefined    let record: RouteRecordRaw    // 如果parentOrRoute是路由名称,parent为parentOrRoute对应的matcher,被增加的route是个嵌套路由    if (isRouteName(parentOrRoute)) {      parent = matcher.getRecordMatcher(parentOrRoute)      record = route!    } else { // 如果parentOrRoute不是路由名称,parentOrRoute就是要增加的路由      record = parentOrRoute    }    // 调用matcher.addRoute增加新的记录    return matcher.addRoute(record, parent)  }

在定义parent时,应用了一个Paramerer<Type>类型,对于该类型的应用可参考https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype。在该办法中,parent的类型会取matcher.addRoute办法中的第2个参数的类型。

isRouteName:通过判断name是否为stringsymbol类型,来决定是不是routeName

export function isRouteName(name: any): name is RouteRecordName {  return typeof name === 'string' || typeof name === 'symbol'}

总结

addRoute外部,首先判断第一个参数是不是routeName,如果是routeName,那么被增加的路由是个嵌套路由,否则为非嵌套路由,最初会调用matcher.addRoute办法增加新的路由记录。