四、路由匹配器 matcher

350 阅读3分钟

本节简单介绍 matcher

章节三最后可知要执行路由实例的 match() 函数,如下图所示:

image.png

呢么接下来,我们就来看一下 this.matcher 到底是什么呢?


matcher 对象定义

在路由的构造函数内定义 this.matcher = createMatcher(options.routes, this); 属性,该函数的参数分别为:用户定义的路由配置、路由实例,该函数的返回值为对象 { addRoutes, match } 且该对象的两个属性都为函数类型。

接下来分析一下 createMatcher(routes, router) 函数,该函数定义在 /src/create-matcher.js 文件内,并且 matcher 的相关实现都是在该文件内。


createMatcher(routes, router) 函数简析

function createMatcher(routes, router) {
    const { pathList, pathMap, nameMap } = createRouteMap(routes);
    ......
    return { addRoutes, match }
}

呢么 createMatcher() 函数的简单定义如上所示,呢么接下来看看 createRouteMap(routes) 函数的作用,如下:

  • 定义变量 pathList 数组类型,存储路由配置中所有的 path
  • 定义变量 pathMap 对象类型,键为 path,值为 routeRecord
  • 定义变量 nameMap 对象类型,键为 name,值为 routeRecord,该值为路由配置生成的路由记录
  • 遍历用户路由配置 routes 并执行 addRouteRecord(pathList, pathMap, nameMap, route); 函数
  • 最后 renturn { pathList、pathMap、nameMap }

呢么我们再分析一下 addRouteRecord(pathList, pathMap, nameMap, route) 函数,如下:

  • 获取路由配置 route 中的 path、name、component 属性,然后生成对应的路由记录 routeRecord 对象
  • 然后再判断路由配置 route 是否有 children 属性,如果有则递归调用该函数生成对应的路由记录
  • pathMap 不包含该 path 则执行 pathList.push(path); pathMap[path] = routeRecord;
  • nameMap 不包含该 name 则执行 nameMap[name] = routeRecord;

由于 pathList、pathMap、nameMap 都是引用类型,所以在遍历整个路由配置 routes 过程中去执行 addRouteRecord() 函数,会不断给他们添加数据。那么经过整个 createRouteMap() 函数的执行,我们得到的就是完整的 pathList、pathMap、nameMap 对象。


addRoutes(routes, router) 函数简析

function addRoutes (routes) {
  createRouteMap(routes, pathList, pathMap, nameMap)
}

该函数的定义如上,该函数的作用就是动态添加路由。就是再次调用 createRouteMap() 函数并传入新增的路由配置,由于 pathList、pathMap、nameMap 都是引用类型,执行 addRoutes() 函数后会动态的修改它们的值。


match(raw, currentRoute, redirectedFrom) 函数简析

在该函数内:

  • 通过 normalizeLocation((raw, currentRoute) 函数计算出新的 location 对象.
  • 获取 location.name 属性,依据 nameMap 匹配到对应的 routeRecord 对象。若不存在则返回一个空路径,若存在则执行 _createRoute(routeRecord, location) 生成新的路径并返回。
  • 获取 location.path 属性,依据 pathMap 匹配到对应的 routeRecord 对象。若不存在则返回一个空路径,若存在则执行 _createRoute(routeRecord, location) 生成新的路径并返回。
  • 最后执行 _createRoute(null, location) 空路径。

函数 _createRoute(routeRecord, location) 相对比较简单,主要功能就是根据 routeRecordlocation 创建出来,最终返回的是一条 Route 路径且不可修改,通过函数 Object.freeze() 实现。

函数 match(raw, currentRoute) 返回的是一个路径,它的作用是根据传入的 raw 和当前的路径 currentRoute 计算出一个新的路径并返回。最后纵观全局 pathList、pathMap、nameMap 三个变量是全局非常重要的数据。该函数也是为了路径切换做准备的。