共计 1431 个字符,预计需要花费 4 分钟才能阅读完成。
前言
【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
是否为 string
或symbol
类型,来决定是不是routeName
。
export function isRouteName(name: any): name is RouteRecordName {return typeof name === 'string' || typeof name === 'symbol'}
总结
在 addRoute
外部,首先判断第一个参数是不是 routeName
,如果是routeName
,那么被增加的路由是个嵌套路由,否则为非嵌套路由,最初会调用matcher.addRoute
办法增加新的路由记录。