vue-router 源码分析——6.命名路由

这是对vue-router 3 版本的源码分析。
本次分析会按以下方法进行:

  1. 按官网的使用文档顺序,围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码,更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升,甚至面试时的回答都非常有帮助。
  2. 在围绕某个功能展开讲解时,所有不相干的内容都会暂时去掉,等后续涉及到对应的功能时再加上。这样最大的好处就是能循序渐进地学习,同时也不会被不相干的内容影响。省略的内容都会在代码中以…表示。
  3. 每段代码的开头都会说明它所在的文件目录,方便定位和查阅。如果一个函数内容有多个函数引用,这些都会放在同一个代码块中进行分析,不同路径的内容会在其头部加上所在的文件目录。

本章讲解router中命名路由是如何实现的。
另外我的vuex3源码分析也发布完了,欢迎大家学习:
vuex3 最全面最透彻的源码分析
还有vue-router的源码分析:
vue-router 源码分析——1. 路由匹配
vue-router 源码分析——2. router-link 组件是如何实现导航的
vue-router 源码分析——3. 动态路由匹配
vue-router 源码分析——4.嵌套路由
vue-router 源码分析——5.编程式导航

源码实现分析:

  • 官方例子
const router = new VueRouter({routes: [{path: '/user/:userId',name: 'user',component: User}]
})<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 } })
  • 回顾一下第一章,即创建vue-router 实例时内部发生了什么。router创建了一个匹配器 this.matcher,在这个内部创建了非常重要的三个数据:pathList、pathMap和nameMap。前两个之前已经介绍过了,现在介绍一下nameMap的数据结构。
  • 从下面的源码可以看出,nameMap 是以使用者定义的每个route的name(如果有)作为key,value为每个route的record。同时name也会添加到record中。
// ./create-route-map.js
export function createRouteMap(routes: Array<RouteConfig>,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)reoutes.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 record: RouteRecord = {name,...}if (name) {if (!nameMap[name]) {nameMap[name] = record        } else if (...) {...}}
}
  • 在上一章vue-router 源码分析——5.编程式导航中已经知道在执行router.push时,调用 this.router.match 创建了一个新的路由对象(即跳转到的路由)。
// ./history/hash.js
export class HashHistory extends History {...push(location: RawLocation, onComplete?: Function, onAbort?: Function)) {...this.transitionTo(location,route => {...             }         )   }
}// ./history/base.js
export class History {...transitionTo(location: RawLocation,onComplete?: Function,onAbort?: Function) {let routetry {route = this.router.match(location, this.current) // 创建新路由}    }
}
  • 在创建新路由时,如果存在name,则通过nameMap来查找并获得相关数据(record)。
  • 通过下面的源码分析,知道了vue-router的两种匹配方式(name和path)的处理逻辑。命名路由name是使用哈希算法来进行匹配,而路径路由path是遍历数组进行匹配。在匹配时,以name匹配优先。
// ./router.js
export default class VueRoute {..match(raw: RawLocation, current?: Route, redirectedFrom?: Location): Route {return this.matcher.match(raw, current, redirectedFrom)    }
}// ./create-matcher.js
export function createMatcher {routes: Array<RouteConfig>,router: VueRouter
}: Matcher {const { pathList, pathMap, nameMap } = createRouteMap(routes)function match(raw: RawLocation,currentRoute?: Route,redirectedFrom?: Location            ): Route {const location = normalizeLocation(raw, currentRoute, false, router)const { name } = locationif (name) {const record = nameMap[name] // 通过nameMap来查找并获得record...location.path = fillParams(record.path, location.params, `named route "${name}"`)return _createRoute(record, location, redirectedFrom)} else if (location.path) {...}}
}

总结

  • 在路由初始化时,收集所有用户定义的命名路由记录到 nameMap 字典结构中。
  • 在路由匹配时,通过name作为key,从 nameMap 中取出对应的路由记录,以此来生成对应url的路由。
  • 命名路由的匹配时间复杂度要优于路径匹配(hashmap-getter 和 数组遍历),所以理论上命名路由的匹配时间要少于路径匹配。如果项目有大量路径匹配的路由时,可以转换成命名路由来优化匹配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/852029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 围棋游戏【含Python源码 MX_008期】

简介&#xff1a; 围棋&#xff0c;源自中国&#xff0c;是一种两人对弈的策略棋类游戏。它被认为是世界上最复杂的棋类游戏之一&#xff0c;因为它的规则简单&#xff0c;但变化复杂多样。围棋的游戏目标是在棋盘上占领更多的地盘&#xff0c;并用自己的棋子围住对手的棋子&am…

docker-compose harbor 2.11

harbor 前言 “Harbor” 是一个用于管理容器镜像的开源仓库项目。由 VMware 开发和维护,Harbor 提供一个企业级的 Docker 镜像仓库,具有丰富的功能,包括: 镜像管理:提供存储和分发 Docker 镜像的能力。安全性:支持镜像签名和漏洞扫描,确保镜像的安全性。身份认证:集成…

项目代码导出到word脚本

需求 之前课程需求&#xff0c;需要将项目代码导出到一个word进行存档。当时就写了这个脚本来进行导出&#xff0c;现在毕业论文又有这个需求了&#xff0c;将这个脚本总结并帮助更多的人。 项目地址github项目&#xff0c;如果有人想更加完美的可以进行修改。 实现与操作 …

Android基础-JNI

一、JNI概述 JNI&#xff0c;全称Java Native Interface&#xff0c;是Java平台标准版&#xff08;Java SE Platform&#xff09;的一部分&#xff0c;它允许Java代码与其他语言写的代码进行交互。在Android系统中&#xff0c;JNI尤为重要&#xff0c;因为它连接了Java层与底层…

MySQL CDC

一、MySQL CDC概念 MySQL CDC&#xff08;Change Data Capture&#xff09;&#xff0c;即MySQL变更数据捕获&#xff0c;是一种能够捕获MySQL数据库中数据变化&#xff08;包括插入、更新和删除操作&#xff09;的技术。这些变化可以实时或准实时地同步到其他系统或服务中&am…

41 mysql subquery 的实现

前言 sub query 是一个我们经常会使用到的一个 用法 我们这里 看一看各个场景下面的 sub query 的相关处理 查看 本文, 需要 先看一下 join 的相关处理 测试数据表如下, 两张测试表, tz_test, tz_test03, 表结构 一致 CREATE TABLE tz_test (id int(11) unsigned NOT NUL…

vuex4.x 升级pinia,router 中使用同步组件导致项目启动失败

背景描述 升级的项目本来是vue2的项目&#xff0c;先升级成vue3&#xff0c;这个过程相关的问题都被决绝&#xff0c;当时状态管理使用的还是vuex4.x版本。 后面发现变成复杂模块时&#xff0c;后续再对复杂模块的功能进行迭代时&#xff0c;由于js的弱类型&#xff0c;改动时…

Python3 数据结构

列表 Python中列表是可变的&#xff0c;这是它区别于字符串和元组的最重要的特点&#xff0c;一句话概括即&#xff1a;列表可以修改&#xff0c;而字符串和元组不能。 以下是 Python 中列表的方法&#xff1a; 方法描述list.append(x)把一个元素添加到列表的结尾&#xff0…

管道(channel)和协程案例

请完成协程和管道协同工作的案例&#xff0c;具体要求&#xff1a; 1、开启一个writeData协程&#xff0c;向管道中写入50个整数 2、开启一个readData协程&#xff0c;从管道中读取writeData写入的数据 3、注意&#xff1a;writeData和readDate操作的是同一个管道 4、主线程需要…

0120__多字节字符vs宽字符

【字符集二】多字节字符vs宽字符-CSDN博客 多字节字符与宽字节字符_宽字符-CSDN博客

热门开源项目推荐:技术与地址概览

随着开源项目的不断兴起&#xff0c;越来越多的优秀项目涌现出来&#xff0c;为开发者们提供了丰富的资源和灵感。在此&#xff0c;我将为大家推荐几个热门的开源项目&#xff0c;并附上它们的开源地址&#xff0c;以供大家参考和了解。 1. TensorFlow 项目简介&#xff1a; …

Get、Post的区别------重定向和转发的区别-----http、https的区别!!!

一、Get和Post的区别 1、用途 Get&#xff1a;用于从服务器请求数据&#xff0c;幂等&#xff0c;不改变服务器的数据。Post&#xff1a;用于向服务器发送数据&#xff0c;可能改变服务器数据。 2、数据传输方式 Get&#xff1a;通过url传参&#xff0c;使用&符号连接多…

QT调用vs2019生成的c++动态库

QT调用vs2019生成的c动态库 dll库的创建方法&#xff1a; VS2019创建c动态链接库dll与调用方法-CSDN博客 加减法示范&#xff1a; 头文件 // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号编…

SurfaceView->SurfaceView基本概念

绘制过程 View和SurfaceView绘制过程 PhoneWindow&#xff1a;Window的具体实现&#xff0c;在Activity中调用setContentView()方法时&#xff0c;一个PhoneWindow实例会对应一个ViewRootImpl实例&#xff0c;绘制&#xff0c;事件分发传递给ViewRootImpl进行ViewRootImpl&…

少样本学习元学习

基本概念 首先是机器学习&#xff1a; 然后&#xff0c;什么是元学习&#xff08;what is meta learning?) 之前&#xff0c;Component都是让人自己设置的。在Meta Learning中&#xff0c;我们期望它能够自己学出来。 不同的meta learning方法就是想办法去学learning algori…

Python记忆组合透明度语言模型

&#x1f3af;要点 &#x1f3af;浏览器语言推理识别神经网络 | &#x1f3af;不同语言秽语训练识别数据集 | &#x1f3af;交互式语言处理解释 Transformer 语言模型 | &#x1f3af;可视化Transformer 语言模型 | &#x1f3af;语言模型生成优质歌词 | &#x1f3af;模型不确…

安卓兼容的编程语言有哪些:探索多样化的开发选择

安卓兼容的编程语言有哪些&#xff1a;探索多样化的开发选择 在安卓应用开发的世界里&#xff0c;编程语言的选择丰富多样&#xff0c;每一种语言都有其独特的优势和适用场景。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入剖析安卓兼容的编程语言&#xf…

【JavaScript脚本宇宙】探索前端图形与图像库:从2D图形到图像懒加载

优化用户体验&#xff1a;探究图像懒加载库的选择 前言 在Web开发中&#xff0c;图形和图像库扮演着至关重要的角色&#xff0c;它们可以让我们轻松地操作和呈现各种图形、图像以及数据可视化。本文将介绍一系列前端开发中常用的图形和图像库&#xff0c;从2D图形到3D图形&am…

指定文件停止git跟踪方法

1、当你已经将一个文件提交到Git仓库&#xff0c;然后将其添加到.gitignore文件中&#xff0c;但Git仍然跟踪该文件时&#xff0c;这是因为Git已经开始跟踪这个文件的历史。要让Git停止跟踪这个文件&#xff0c;你需要从Git的索引中显式地删除它。以下是解决这个问题的步骤&…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(二)

主要内容介绍可tmux和vim的一些常用操作&#xff0c;可以当作笔记需要的时候进来查就行。 文章目录 前言 一、tmux和vim 二、Linux系统基本命令 1.tmux教程 2. vim教程 3.练习 总结 前言 主要内容介绍可tmux和vim的一些常用操作&#xff0c;可以当作笔记需要的时候进来查就行…