vue-router 源码分析——8.重定向

这是对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.编程式导航
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)
}

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

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

相关文章

python连接clickhouse,UnexpectedPacketFromServerError: Code: 102

安装驱动 pip install clickhouse-driver本地环境 python Python 3.8.8 clickhouse-driver 0.2.8 clickhouse server 20.3https://github.com/mymarilyn/clickhouse-driver https://clickhouse-driver.readthedocs.io/en/latest/installation.html from clickhouse_driver i…

基于Spring Boot框架的EAM系统设计与实现

摘 要&#xff1a;文章设计并实现一个基于Spring Boot框架的EAM系统&#xff0c;以应对传统人工管理模式存在的低效与信息管理难题。系统利用Java语言、JSP技术、MySQL数据库等技术栈&#xff0c;构建了一个B/S架构的高效管理平台&#xff0c;提升了资产管理的信息化水平。该系…

如何在Java中实现PDF生成

如何在Java中实现PDF生成 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在软件开发和企业应用中&#xff0c;生成PDF文档是一项常见的需求。Java作为一种强大…

一个小公司的技术开发心酸事

背景 长话短说&#xff0c;就是在2022年6月的时候加入了一家很小创业公司。老板不太懂技术&#xff0c;也不太懂管理&#xff0c;靠着一腔热血加上对实体运输行业的了解&#xff0c;加上盲目的自信&#xff0c;贸然开始创业&#xff0c;后期经营困难&#xff0c;最终散伙。 自己…

独立站外链的重要性是什么?

独立站外链在提升网站排名和增加流量方面有着重要的作用。简单来说&#xff0c;外链就是从其他网站指向你网站的链接。谷歌和其他搜索引擎会根据这些外链来判断你网站的权威性和相关性。 有了高质量的外链&#xff0c;搜索引擎会更倾向于认为你的网站内容是有价值的&#xff0c…

c++ 附赠课程的知识点记录

&#xff08;1&#xff09; 静态变量的赋值 再一个例子&#xff1a; &#xff08;2&#xff09; 一般在定义类的赋值运算符函数时&#xff0c; operator ( const A& a ) 函数&#xff0c;应避免自赋值的情况&#xff0c;就是把对象 a 又赋值给 对象a 如同 a a 这样的情况…

如何摆脱反爬虫机制?

在网站设计时&#xff0c;为了保证服务器的稳定运行&#xff0c;防止非法数据访问&#xff0c;通常会引入反爬虫机制。一般来说&#xff0c;网站的反爬虫机制包括以下几种&#xff1a; 1. CAPTCHA&#xff1a;网站可能会向用户显示CAPTCHA&#xff0c;要求他们在访问网站或执行…

空状态页面设计的艺术与科学

空状态界面是用户在网站、APP中遇到的因无数据展示而中断体验的界面&#xff0c;这个界面设计对于解决用户疑惑有着很大的帮助。那么我们应该如何设计空状态界面呢&#xff1f;空状态是指在界面设计中&#xff0c;没有内容或数据时所显示的状态。它可能出现在各种情况下&#x…

CentOS 7 搭建rsyslog日志服务器

CentOS 7 搭建rsyslog日志服务器 前言一、IP地址及主机名称规划1.修改主机名 二、配置rsyslog日志服务器1.安装rsyslog服务2.编辑/etc/rsyslog.conf 文件3.启动并启用rsyslog服务4.验证端口是否侦听 三、在rsyslog日志服务器上配置firewalld防火墙四、配置rsyslog日志客户端1.编…

【代码随想录算法训练营第37期 第三十八天 | LeetCode509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯】

代码随想录算法训练营第37期 第三十八天 | LeetCode509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 一、509. 斐波那契数 解题代码C&#xff1a; class Solution { public:int fib(int N) {if (N < 2) return N;return fib(N - 1) fib(N - 2);} };题目链接/文章讲…

刷算法Leetcode---8(二叉树篇)(层序遍历)

前言 本文是跟着代码随想录的二叉树顺序进行刷题并编写的 代码随想录 二叉树的题目较多&#xff0c;就多分了几次写&#xff0c;这是第二篇 第一篇二叉树的文章链接&#xff1a;刷算法Leetcode---7&#xff08;二叉树篇&#xff09;&#xff08;前中后序遍历&#xff09; 这是力…

超实用的VS Code插件推荐

VS Code代码编辑器中提供了丰富的插件&#xff0c;满足不同开发者的需求。这里为大家推荐一些强大的VS Code插件&#xff0c;帮助你打造一个个性化的开发环境&#xff0c;让你的编码体验更加舒适和高效。 打开扩展模块&#xff0c;输入安装包名称&#xff0c;回车进行搜索&…

【WSL】常用命令

文章目录 启动 WSL列出 Linux 发行版安装 Linux 发行版设置默认的 Linux 发行版卸载 Linux 发行版更新 WSL检查 WSL 状态启动和关闭 WSL跨系统文件访问其他命令 Windows Subsystem for Linux (WSL) 提供了一系列命令用于管理 Linux 发行版在 Windows 系统中的运行。下面是一些常…

【Qt之·类QVariant·数据类型】

系列文章目录 文章目录 前言一、概述二、操作及用法1.1 存储数据1.2 获取数据1.3 设置数据1.4 数据类型判断1.5 判断数据是否有效 三、实例演示总结 前言 QVariant是Qt开发中非常重要的一部分&#xff0c;它是Qt的一个核心类&#xff0c;用于处理不同数据类型之间的转换和传递。…

微服务框架Kratos学习笔记

环境配置 export GOPROXYhttps://goproxy.cn export GO111MODULEon go get -u github.com/go-kratos/kratos/tool/kratoskratos 工具安装完成 使用kratos命令创建新项目 kratos new kratos-demo看到这个提示&#xff0c;项目创建完成 go mod tidy 拉取项目依赖 生成所有pro…

保险研究期刊

《保险研究》创刊于1980年&#xff0c;是国家金融监督管理总局主管的学术性保险期刊&#xff0c;是中国保险学会会刊&#xff0c;是中文社会科学引文索引&#xff08;CSSCI&#xff09;来源期刊、中文核心期刊、中国人文社会科学核心期刊、人大“复印报刊资料”重要转载来源期刊…

二、从多臂老虎机看强化学习

二、从多臂老虎机看强化学习 2.1 多臂老虎机问题2.1.1 问题定义2.2.2 问题建模2.2.3 累积懊悔2.2.4 估计期望奖励 2.2 强化学习中的探索与利用平衡2.3 贪心策略2.4 上置信界算法2.5 汤普森采样算法 2.1 多臂老虎机问题 2.1.1 问题定义 在多臂老虎机(mutil-armed bandit, MAB)问…

科研绘图系列:R语言点数图(dot plot)

介绍 点数图(Dot Plot)是一种数据可视化方法,它通过在坐标轴上放置点来展示数据。每个点代表一个数据项,点的位置通常对应于数据值的大小。点数图可以有效地展示多个类别或组的数值比较,使得观察者能够快速识别出哪些类别的数值较高或较低。 加载R包 library(tidyverse…

离线升级docker中的某个镜像——以etcd为例

之前有个项目的程序统一在docker中运行&#xff0c;最近在做安全检查时&#xff0c;发现docker的部分image因为版本没有更新到最新而出现安全漏洞问题。 本贴记录linux环境中&#xff0c;升级docker中某个镜像的步骤&#xff0c;详情如下&#xff1a; 一、生成镜像的步骤&…

ES集成到ambari中出现的常见问题归总

1.elasticesearch用户名组的问题 KeyError: uelasticsearch Error: Error: Unable to run the custom hook script [/usr/bin/python, /var/lib/ambari-agent/cache/stack-hooks/before-ANY/scripts/hook.py, ANY, /var/lib/ambari-agent/data/command-102.json, /var/lib/amb…