vue-router 源码分析——8.重定向
这是对vue-router 3 版本的源码分析。
本次分析会按以下方法进行:
- 按官网的使用文档顺序,围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码,更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升,甚至面试时的回答都非常有帮助。
- 在围绕某个功能展开讲解时,所有不相干的内容都会暂时去掉,等后续涉及到对应的功能时再加上。这样最大的好处就是能循序渐进地学习,同时也不会被不相干的内容影响。省略的内容都会在代码中以…表示。
- 每段代码的开头都会说明它所在的文件目录,方便定位和查阅。如果一个函数内容有多个函数引用,这些都会放在同一个代码块中进行分析,不同路径的内容会在其头部加上所在的文件目录。
本章讲解router中重定向是如何实现的。
另外我的vuex3源码分析也发布完了,欢迎大家学习:
vuex3 最全面最透彻的源码分析
还有vue-router的源码分析:
vue-router 源码分析——1. 路由匹配
vue-router 源码分析——2. router-link 组件是如何实现导航的
vue-router 源码分析——3. 动态路由匹配
vue-router 源码分析——4.嵌套路由
vue-router 源码分析——5.编程式导航
vue-router 源码分析——6.命名路由
vue-router 源码分析——7.命名视图
官方示例:
- 重定向是通过 routes 配置来完成,重定向的目标也可以是一个命名路由,或者一个方法。
const router = new VueRouter({routes: [{ path: '/a', redirect: '/b' },{ path: '/b', component: b_component} // 重定向的路由必须在router中定义]
})const router = new VueRouter({routes: [{ path: '/a', redirect: { name: 'foo' }}]
})const router = new VueRouter({routes: [{ path: '/a', redirect: to => {// 方法接收 目标路由 作为参数// return 重定向的 字符串路径/路径对象}}]
})
Router初始化:
- Router初始化生成匹配器和路由记录表,redirect属性会被复制到路由的路由记录上:
// router.js
import type { Matcher } from './create-matcher'
export default class VueRouter {...constructor(options: RouterOptions = {}) {...this.matcher = createMatcher(options.routes || [], this)}
}// ./create-matcher.js
import { createRouteMap } from './create-route-map'
export function createMatcher(routes: Array<RouteConfig>,router: VueRouter
): Matcher {const { pathList, pathMap, nameMap } = createRouteMap(routes)...
}// ./create-route-map/js
export function createRouteMap(routes: Array<RouteConfig>,...
): {pathList: Array<string>,pathMap: Dictionary<RouteRecord>,nameMap: Dictionary<RouteRecord>
} {const pathList: Array<string> = []const pathMap: Dictionary<RouteRecord> = Object.create(null)const nameMap: Dictionary<RouteRecord> = Object.create(null)routes.forEach(route => {addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)})...
}function addRouteRecord(pathList: Array<string>,pathMap: Dictionary<RouteRecord>,nameMap: Dictionary<RouteRecord>,route: RouteConfig,parent?: RouteRecord,matchAs?: string
) {...const record: RouteRecord = {redirect: route.redirect,... }
}
触发逻辑:
- 当试图跳转到url ‘/a’ 时,会触发路由匹配。
- 首先匹配到路由路径为’/a’的路由记录,然后判断它是否有redirect属性,如果有就执行redirect函数。
- 接着在redirect函数中取出redirect内容,对其进行了结构类型统一化。这里就解释了为什么配置重定向的目标可以是字符串形式的path,或者命名路由,或者方法。
- 最后,构建了一个基于redirect目标的数据,作为参数传入match函数进行路由匹配。这样的递归调用也能解决多重的重定向。
// 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) {// 基于命名路由的匹配逻辑 } else if (location.path) {location.params = {}for (let i = 0; i < pathList.length; i++) {const path = pathList[i]const record = pathMap[path]if (matchRoute(record.regex, location.path, location.params)) {// 这里匹配到路由'/a'的相关记录后,执行创建路由的操作return _createRoute(record, location, redirectedFrom)}} }}function _createRoute(record: ?RouteRecord,location: Location,redirectedFrom?: Location ): Route {// 如果当前的路由记录有重定向,就执行重定向的相关逻辑,否则创建'/a'的路由内容if (record && record.redirect) {return redirect(record, redirectedFrom || location) }...return createRoute(record, location, redirectedFrom, router)}function redirect(record: RouteRecord,location: Location): Route {const originalRedirect = record.redirect// 下面这段代码解释了为什么重定向可以是一个方法,同时接受的参数是目标路由,let redirect = typeof originalRedirect === 'function'? originalRedirect(createRoute(record, location, null, router)): originalRedirect// 最后无论重定向设置的是字符串,命名路由,方法,都会统一成一个对象结构if (typeof redirect === 'string') {redirect = {path = redirect} }...const re: Object = redirectconst { name, path } = re...if (name) {const targetRecord = nameMap[name]...return match({name,... }, undefined, location) } else if (path) {const rawPath = resolveRecordPath(path, record) const resolvedPath = fillParams(rawPath, params, `redirect route with path "${rawPath}"`)return match({path: resolvedPath, // 官网示例中定义的重定向都不复杂,这里的path = '/b'没有任何改变... }, undefined, location) }}
}
细节补充:
- 当重定向完成,匹配路由成功后,调用createRoute函数生成匹配路由时,增加了一个redirectedFrom属性,记录的是它的重定向的源路径。这样可以方便用户查看或者执行其他功能。
// ./util/route.js
export function createRoute(record: ?RouteRecord,location: Location,redirectedFrom?: ?Location,router?: VueRouter
): Route {...const route: Route = {... }if (redirectedFrom) {route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery) }return Object.freeze(route)
}
相关文章:
vue-router 源码分析——8.重定向
这是对vue-router 3 版本的源码分析。 本次分析会按以下方法进行: 按官网的使用文档顺序,围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码,更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升,甚至面试时…...
CAN总线协议
CAN总线协议,全程为控制器局域网(Controller Area Network)协议,是一种用于实时应用的串行通讯协议。该协议由德国某公司专门为汽车行业开发,并逐渐成为一种标准,这是国际上应用最广泛的现场总线之一。 一…...
NLP篇1
场景:假设给你一篇文章。 目标:说白了,就是数学的分类。但是如何实现分类呢。下面将逐步一 一 分析与拆解。先把目标定好了和整体框架定好了。而不是只见树木而不见森林。 情感分类(好评、差评,中性) 整体…...
【一念发动便是行】念头,就是命运
一个个恶念累积就是负能量,念头就是命运,克除恶念,防范念头,念头都有能量,学圣学须内外庄严检肃,言语有灵 多数人的问题都是出在念头上,念头,就是自己的命运; 当我们对自…...
Django + Vue 实现图片上传功能的全流程配置与详细操作指南
文章目录 前言图片上传步骤1. urls 配置2. settings 配置3. models 配置4. 安装Pillow 前言 在现代Web应用中,图片上传是一个常见且重要的功能。Django作为强大的Python Web框架,结合Vue.js这样的现代前端框架,能够高效地实现这一功能。本文将…...
【介绍下R-tree,什么是R-tree?】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...
每天10个js面试题(二)
1.事件轮询? JavaScript 是单线程的,同一时间只能做一件事。所有任务都需要排队,前一个任务结束,才会执行后一个任务,为了保证任务有序的执行,事件轮询就是单线程任务调度的一种方式,单线程任务…...
深入理解【 String类】
目录 1、String类的重要性 2、常用方法 2、1 字符串构造 2、2 String对象的比较 2、3 字符串查找 2、4字符转换 数值和字符串转换: 大小写转化: 字符串转数组: 格式转化: 2、5 字符串替换 2、6字符串拆分 2、7 字符串…...
Nacos 2.x 系列【20】集群部署
文章目录 1. 前言2. 部署服务端2.1 准备工作2.2 集群节点配置2.3 鉴权配置2.4 配置数据源2.5 配置 IP2.6 配置端口2.7 启动集群 3. 部署模式3.1 直连模式3.2 地址服务器模式3.2.1 地址服务器3.2.2 配置 3.3 VIP 模式(推荐)3.3.1 Nginx3.3.1 域名 1. 前言…...
LeetCode刷题记录:(15)三角形最小路径和
知识点:倒叙的动态规划 题目传送 解法一:二维动态规划【容易理解】 class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n triangle.size();if (n 1) {return triangle.get(0).get(0);}// dp[i][j]:走到第i层第…...
【大数据面试题】35 Spark 怎么做优化?
一步一个脚印,一天一道大数据面试题 博主希望能够得到大家的点赞收,藏支持!非常感谢~ 点赞,收藏是情分,不点是本分。祝你身体健康,事事顺心! Spark 如何做优化一直是面试过程中常问的问题。那么这次也仅以此篇文章总结梳理,希望对大家有帮助。 通用优化 Spark 一般遇…...
2024年保安员职业资格考试题库大数据揭秘,冲刺高分!
186.安全技术防范是一种由探测、()、快速反应相结合的安全防范体系。 A.保安 B.出警 C.延迟 D.监控 答案:C 187.安全技术防范是以()和预防犯罪为目的的一项社会公共安全业务。 A.预防灾害 B.预防损失 C.预防失…...
怎么搭建个人博客教程,附云主机选购指南
一、搭建个人博客教程 1. 规划博客内容与技术栈 确定博客主题:首先明确博客的定位和主题,这将影响后续的技术选择和内容规划。选择技术栈:根据个人偏好和技术背景,选择合适的建站技术。例如,可以使用WordPress&#…...
使用Llama3/Qwen2等开源大模型,部署团队私有化Code Copilot和使用教程
目前市面上有不少基于大模型的 Code Copilot 产品,部分产品对于个人开发者来说可免费使用,比如阿里的通义灵码、百度的文心快码等。这些免费的产品均通过 API 的方式提供服务,因此调用时均必须联网、同时需要把代码、提示词等内容作为 API 的…...
C语言_结构体初阶(还未写完)
结构体的声明 1. 什么是结构?结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量 数组:一组相同类型元素的集合 结构体:一组不一定相同类型元素的集 2. 结构的声明 struct tag //tag根据实际情况给名字…...
MyBatis-Plus:快速入门
1. 概念 MyBatis-Plus(简称 MP)是一个MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。其突出的特性如下: * **无侵入**:只做增强不做改变,引入它不会对现有…...
【高级篇】第9章 Elasticsearch 监控与故障排查
9.1 引言 在现代数据驱动的应用架构中,Elasticsearch不仅是海量数据索引和搜索的核心,其稳定性和性能直接影响到整个业务链路的健康度。因此,建立有效的监控体系和掌握故障排查技能是每一位Elasticsearch高级专家的必备能力。 9.2 监控工具:洞察与优化的利器 在Elastics…...
【前端】上传和下载zip文件,有进度条(el-progess)
文章目录 上传下载进度条 场景:要上传一个zip,调用接口,然后下载一个zip。调用接口的接口响应要显示在进度条中。 上传 上传用的是input原生控件,在页面中隐藏。accept"application/zip"限制只能上传zip。 点击button…...
2024年软件测试面试题,精选100+,附答案+文档
🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 Part1 1、你的测试职业发展是什么? 测试经验越多,测试能力越高。所以我…...
在vue项目的.gitignore文件忽略不想要提交到git仓库的文件
在Vue项目中,使用.gitignore文件来忽略不需要提交到Git仓库的文件是一个常见的做法。.gitignore文件包含了一系列的规则,这些规则告诉Git哪些文件或目录应该被忽略。以下是一些Vue项目中常用的.gitignore文件示例和具体规则说明: 示例 .gitig…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
