We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
分析目标,router-view 如何正确渲染对应的组件。
根据我们自定义的路由规则,初始化路由项,通过遍历递归的方式建立路由索引 pathMap,nameMap,pathList 和父子路由之间的引用关系(子路由有 parent 属性,指向父路由)
// 省略一些细节,只关注核心代码逻辑 function addRouteRecord ( pathList: Array<string>, pathMap: Dictionary<RouteRecord>, nameMap: Dictionary<RouteRecord>, route: RouteConfig, parent?: RouteRecord, matchAs?: string ) { const { path, name } = route // ...省略 const record: RouteRecord = { // ...省略 path: normalizedPath, components: route.components || { default: route.component }, name, parent, // ...省略 } ... if (route.children) { // ...省略 route.children.forEach(child => { const childMatchAs = matchAs ? cleanPath(`${matchAs}/${child.path}`) : undefined addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs) }) } // ...省略 }
路由切换的时候,都是通过 match 函数找到目标路由。
/** * 可以看到这里调用_createRoute返回对应的路由项 * 省略一些细节,只关注核心代码逻辑 * */ function match ( raw: RawLocation, currentRoute?: Route, redirectedFrom?: Location ): Route { // ...省略 const location = normalizeLocation(raw, currentRoute, false, router) const { name } = location if (name) { const record = nameMap[name] // ...省略 return _createRoute(record, location, redirectedFrom) } // ...省略 } /** * 调用真正的生成路由项的函数createRoute * */ function _createRoute ( record: ?RouteRecord, location: Location, redirectedFrom?: Location ): Route { // ...省略 return createRoute(record, location, redirectedFrom, router) } /** * 路由项里面有一个属性matched,是由formatMatch格式化record之后返回的,后面router-view里面将用到这个* 属性来展示对应的组件 * */ export function createRoute ( record: ?RouteRecord, location: Location, redirectedFrom?: ?Location, router?: VueRouter ): Route { const stringifyQuery = router && router.options.stringifyQuery // ...省略 const route: Route = { // ...省略 name: location.name || (record && record.name), params: location.params || {}, matched: record ? formatMatch(record) : [] // // ...省略 } return Object.freeze(route) } /** * 根据初始化的时候建立的父子关系,返回matched的路由及其父级 * */ function formatMatch (record: ?RouteRecord): Array<RouteRecord> { const res = [] while (record) { res.unshift(record) record = record.parent } return res }
router-view 组件核心思想之一就是找到 router-view 之间嵌套的深度
/** * depth表示当前组件的层级 * */ while (parent && parent._routerRoot !== parent) { const vnodeData = parent.$vnode ? parent.$vnode.data : {}; if (vnodeData.routerView) { depth++; } if (vnodeData.keepAlive && parent._directInactive && parent._inactive) { inactive = true; } parent = parent.$parent; } // ...省略 /** * 结合之前我们分析matched的定义和depth的概念,可以得到当前router-view需要渲染的组件 * */ const matched = route.matched[depth]; const component = matched && matched.components[name];
The text was updated successfully, but these errors were encountered:
No branches or pull requests
路由初始化
路由匹配
路由展示
The text was updated successfully, but these errors were encountered: