vue-router 源码分析——1. 路由匹配

小伙伴们晚上好,今天开一个新坑——vue-router的源码分析。

vuex的源码分析已经发布完了,感兴趣的小伙伴可以看我之前发的文章。

源码分析步骤也是和之前一样的,积沙成塔式地学习源码。根据官网的内容来分析,重点关注某一功能是如何实现的。

创建vue-router 实例时内部发生了什么

  • 假设最基本的情况,即官网中的入门示例:

const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] const router = new VueRouter({ routes // (缩写) 相当于 routes: routes })

  • 在实例化的过程中创建 matcher 匹配器,调用了 createMatcher 函数

// ./router.js import type { Matcher } from './create-matcher' export default class VueRouter { matcher: Matcher constructor (options: RouterOptions = {}) { this.matcher = createMatcher(options.routes || [], this) } }

  • 在 createMatcher 函数中调用 createRouteMap 函数创建了一系列和path相关的数据,并返回包含自己内容定义的一些函数组成的对象。

// createMatcher函数 ./create-matcher.js import { createRouteMap } from './create-route-map' export function createMatcher(routes, route): { const {pathList, pathMap, nameMap } = createRouteMap(routes) function match() {} function addRoute() {} function getRoutes() {} function addRoutes() {} return { match, addRoute, getRoutes, addRoutes } }

  • createRouteMap函数利用routes数据得出上面需要的对象内容(pathList, pathMap, nameMap),对应 ./create-route-map.js 文件。

  • 内部遍历routes => route,并调用 addRouteRecord 函数。

  • 对每个route的path,调用 normalizePath 函数规范化。

  • 构建一个 record 对象,基本内容还是和route一样,比如path, component。component这里有一个逻辑或运算符,是用来处理命名视图的,可以先不管。

  • pathList 记录每个record的path。

  • pathMap 记录record的path和record的映射关系。

  • nameMap 记录name(命名路由)和recoed的映射关系。

export function createRouteMap( routes: Array<RouteConfig>, // 下面的其他参数可先不管,因为只传了routes入参,都可看做undefine or any oldPathList?: Array<string>, oldPathMap?: Dictionary<RouteRecord>, oldNameMap?: Dictionary<RouteRecord>, parentRoute?: RouteRecord ): { pathList: Array<string>, pathMap: Dictionary<RouteRecord>, nameMap: Dictionary<RouteRecord> } { // 初始化都是空数组和空字典 const pathList: Array<string> = oldPathList || [] const pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null) const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null) routes.forEach(route => { addRouteRecord(pathList, pathMap, nameMap, route, parentRoute) }) return { pathList, pathMap, nameMap } } function addRouteRecord( pathList: Array<string>, pathMap: Dictionary<RouteRecord>, nameMap: Dictionary<RouteRecord>, route: RouteConfig, parent?: RouteRecord, matchAs?: string ) { const { path, name } = route const pathToRegexpOptions = {} // path 规范化 const normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict) const record: RouteRecord = { path: normalizedPaath, components: route.components || { default: route.component }, ... } // 记录 pathList 和 pathMap 的内容 if (!pathMap[record.path]) { pathList.push(record.path) pathMap[record.path] = record } } function normalizePath( path: string, parent?: RouteRecord, strict?: boolean ) { if (!strict) path = path.replace(/\/$/, '') // 将path尾部的 / 去掉(如果有) if (path[0] == '/') return path }

  • 至此,router在初始化时,创建了一个 VueRouter类,里面有一个 matcher属性,包含了用户定义的路由的path、components和相关的匹配逻辑函数,以及三张路由记录表。

  • 下一章会分析 router-link 组件是如何实现导航的。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
zest
作者分享
最近业务需要,计划招多名短期兼职,时长半个月左右,做数据标注任务。 要求理解标注规则,(修改一下)按数量付钱,多劳多得,但是必须在某个规定时间内完成,需要有充足的时间。最好有标注经验。 可远程,有需要的结束后可开实习证明。 感兴趣的加我微信详谈。
7
有没有学习 Python 的鱼友,有用 Python 开发鱼皮项目的经验。 boss 上看了一堆都没匹配上,在这里随缘发一发。 应届或者毕业一年以内,计算机基础扎实,刷过题,有项目经验。 base 深圳南山区,薪资 15k-20k。 除了后端,还能接触到前端和大模型的方向,对职业发展非常有帮助。 感兴趣并且符合要求的加我微信 15773283322
5
新年伊始,招聘一名全栈(偏前端)工程师
5
站在面试官的角度,分析如何更好地应对面试
15
我又来招人了~ 这次是招一名实习生,做 AI 大模型 agent 应用开发。 基于上次招人的情况,我这里做了一些规定和要求,希望有意向的小伙伴能认真看完下面的内容并考虑清楚后再来投递简历。 岗位名称:大模型应用开发工程师 地点:深圳南山科技园 时间:至少实习3个月,周末双休 年限要求:应届实习 岗位要求: 1. 计算机相关专业,最好是大四或研二; 2. 熟悉 Python 语言,具有扎实的数据结构和算法功底; 3. 对基于AI大模型的应用开发感兴趣; 4. 时间比较充裕,能到公司坐班; 5. 良好的沟通能力、学习能力、和团队协作精神; 工作内容: 1. 基于大模型的 agent 应用开发; 2. 基于场景对 Prompt 进行设计和测评,提升大模型效果和稳定性; 3. 根据公司业务需求,与开发团队、产品运营团队紧密配置,持续改进应用; 感兴趣的小伙伴可以添加我微信 15773283322 --------------------------------------------------------------- 随便说一下,上次发布的招聘,也成功地在编程导航上找到了满意的候选人,目前已经入职半个月多了。 上次招人收到了很多人的简历,但是就简历质量而言,真的是一言难尽。 这周末我找时间输出一篇站在面试官的角度看待招聘过程的感受,写一些对焦虑难找工作的人的一些建议。 这里提一句就是真的要好好准备简历啊!
9
下载 APP