0127-2-Vue深入学习5—Vue-Router路由模式

image-20210723191207467

1、Vue-Router三种路由模式:
  • hash:#️⃣使用URL hash 值来做路由,支持所有路由器
  • history:📖依赖HTML5 History API和服务器配置;
  • abstract:⛓支持所有JS运行环境,Node.js服务端;

1.1、路由作用:根据不同的路径,来映射到不同的视图;

1.2、路由基本使用

<div id="app"><h1>Hello  kuishou!</h1><p><!--<router-link>默认会被渲染成一个`<a>`标签--><router-link to="/foo"> 睡觉 Foo</router-link><router-link to="/bar"> 敲代码 bar</router-link></p><!--路由匹配到的组件将渲染在这里--><router-view></router-view>
</div>
import Vue from 'vue'
import VueRouter from  'vue-router'
// 注册路由
Vue.use(VuerRouter)
// 1.定义组件
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2.定义路由
const routes = [{ path: '/foo', components: Foo },{ path: '/bar', components: Bar },
]
2路由注册:

2.1、Vue插件的注册原理: 每个插件都需要实现一个静态的 install 方法,当我们执行 Vue.use 的时候,就会执行这个 install 方法,并且在这个 install 方法中第一个参数拿到 Vue 对象。

3、路由安装:

Vue-Router 安装最重要的一步就是利用 Vue.mixin 去把 beforeCreatedestroyed 两个钩子函数注入到每一个组件中,在beforeCreateed 中定义 私有属性和初始化 路由。

// install.js
// 把  _Vue  export 出去,在源码的任何地方都可以访问 Vue
export let _Vueexport function install (Vue) {// 判断是否有注册指令,如果多次执行install方法,则会returnif (install.installed && _Vue === Vue) returninstall.installed = true// 使用下划线 _Vue 保留 传过来的Vue_Vue = Vueconst isDef = v => v !== undefinedconst registerInstance = (vm, callVal) => {let i = vm.$options._parentVnodeif (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {i(vm, callVal)}}// mixin 作用:把mergeOptions 扩展到全局的 options Vue.mixin({// 这样的话,每一个组件都有beforeCreate、destroyed这两个钩子函数beforeCreate () {if (isDef(this.$options.router)) {this._routerRoot = thisthis._router = this.$options.routerthis._router.init(this)Vue.util.defineReactive(this, '_route', this._router.history.current)} else {this._routerRoot = (this.$parent && this.$parent._routerRoot) || this}registerInstance(this, this)},destroyed () {registerInstance(this)}})
3、VueRouter对象:

当我们执行 new VueRouter 时,beforeCreated 钩子函数会执行 router.init 方法,

 constructor (options: RouterOptions = {}) {this.app = null  // 根 Vue 实例this.apps = []   // 保存所有子组件的 Vue 实例this.options = options // 保存传入的路由配置this.beforeHooks = []  // 钩子函数this.resolveHooks = [] // 钩子函数this.afterHooks = []   // 钩子函数// 路由匹配器this.matcher = createMatcher(options.routes || [], this)// 路由创建的三种模式: hash、history、abstractlet mode = options.mode || 'hash'// 路由创建失败的回调函数,检测浏览器中有没有历史记录(history)this.fallback =mode === 'history' && !supportsPushState && options.fallback !== false// 路由历史的具体的实现实例, 如果没有则会使用hsah访问if (this.fallback) {mode = 'hash'}if (!inBrowser) {mode = 'abstract'}this.mode = modeswitch (mode) {case 'history':this.history = new HTML5History(this, options.base)breakcase 'hash':this.history = new HashHistory(this, options.base, this.fallback)breakcase 'abstract':this.history = new AbstractHistory(this, options.base)breakdefault:if (process.env.NODE_ENV !== 'production') {assert(false, `invalid mode: ${mode}`)}}}
4、Matcher

路由匹配器,主要通过 matchermatch方法 ,匹配路径 Router 的.

  • 4.1、createRouteMap 函数是把用户的 路由配置 转换成一张 路由映射表
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 || []// $flow-disable-lineconst pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null)// $flow-disable-lineconst nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null)// 对路由数组进行遍历routes.forEach(route => {// 遍历成功·拿到每个路由对象addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)})
  • 4.1、createMatcher的初始化逻辑

createMatcher 首先执行的逻辑是 ````const { pathList, pathMap, nameMap } = createRouteMap(routes) ```用来创建一个映射表

  // 对路由数组进行遍历routes.forEach(route => {// 遍历成功·拿到每个路由对象addRouteRecord(pathList, pathMap, nameMap, route, parentRoute)})
  • 4.3、match 的匹配过程

**match 方法作用:**根据传入的 raw 和当前的路径 currentRoute 计算一个新的路径并返回。

match 方法接收3个参数:raw(Location 对象)、currentRoute(当前的路径)、redirectedFrom(与重定向相关

function match (raw: RawLocation, // url 字符串,也可以是⼀个 Location 对象currentRoute?: Route, // Router 类型,表示当前的路径redirectedFrom?: Location // 与重定向相关): Route {// 根据 raw , current 计算出新的 location const location = normalizeLocation(raw, currentRoute, false, router)const { name } = location// 如果current传入属性有nameif (name) {// 根据nameMap 匹配到 record const record = nameMap[name]if (process.env.NODE_ENV !== 'production') {warn(record, `Route with name '${name}' does not exist`)}// 如果 record 不存在,则匹配失败!if (!record) return _createRoute(null, location)const paramNames = record.regex.keys.filter(key => !key.optional).map(key => key.name)if (typeof location.params !== 'object') {location.params = {}}if (currentRoute && typeof currentRoute.params === 'object') {for (const key in currentRoute.params) {if (!(key in location.params) && paramNames.indexOf(key) > -1) {location.params[key] = currentRoute.params[key]}}}location.path = fillParams(record.path, location.params, `named route "${name}"`)return _createRoute(record, location, redirectedFrom)} 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)) {return _createRoute(record, location, redirectedFrom)}}}// no matchreturn _createRoute(null, location)}

5、路径切换

发生路径切换的时候,执行的一系列钩子函数。

image-20210723205053608

  • 5.1、导航守卫的执行流程:

    Vue项目中,导航被触发后,失活的组件(叛变的人)开始调用beforeRouteLeave ,全局守卫(大哥) beforeEach 、组件内的守卫(三弟)重用组件 beforeRouterUpdate 被逐步触发;路由守卫(二哥)在路由配置里调用 beforeEnter 后开始解析异步路由组件;在被激活的目标组件(敌人)里调用beforeRouteEnter ;全局守卫(大哥)beforeResolve检测到目标组件(敌人)被激活(打败),在router.js中查找到需要跳转的导航并被确认,afterEach钩子被调用,最终触发DOM更新;路由守卫(二哥)调用 beforeRouteEnter 传给next的回调函数。

// 全局守卫
router.beforeEach((to, from, next)=>{// 进入路由前首先检查是否登录,如果没有则跳转到登录的视图组件if(to.name != 'Login' && !isAuthenticated) next({ name: 'Login'// 否则继续下一个脚本}) else  {next()}
}) 

image-20210723204800587

参考:https://www.jianshu.com/p/60da87d4ec92

官方文档:Vue-Router

守卫识别路由的三把钥匙:

to : 即将进入的路由

from : 即将离开的路由

next : 进行管道中的下一个钩子

面试题:给路由组件传递数据有哪几种方式?

1、通过 params 传递

// params 不能与 path 一起使用
router.push({ path: './details', parmas: { id: '001'} }) // ->跳转到details

2、通过 query 传递

this.$router.push({ path: '/details/001', query: { kind: "car" }})

3、通过 hash传递

this.$touter.push({ path: './details001', hash: '#car'})

  • 5.2、URL变化的逻辑

  • 5.3、组件渲染的逻辑

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

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

相关文章

安全防御{第三次作业(在第二次作业上添加点需求)}

目录 需求&#xff1a; 拓扑图&#xff1a; 注意&#xff1a;先打开防火墙web界面&#xff0c;在此不做演示 1.要求一&#xff1a;&#xff0c;生产区在工作时间内可以访问服务器区&#xff0c;仅可以访问http服务器 2.要求二&#xff1a;办公区全天可以访问服务器区&#…

使用一个定时器(timer_fd)管理多个定时事件

使用一个定时器(timer_fd)管理多个定时事件 使用 timerfd_xxx 系列函数可以很方便的与 select、poll、epoll 等IO复用函数相结合&#xff0c;实现基于事件的定时器功能。大体上有两种实现思路&#xff1a; 为每个定时事件创建一个 timer_fd&#xff0c;绑定对应的定时回调函数…

考研C语言刷题基础篇之分支循环结构基础(二)

目录 第一题分数求和 第二题&#xff1a;求10 个整数中最大值 第三题&#xff1a;在屏幕上输出9*9乘法口诀表 第四题&#xff1a;写一个代码&#xff1a;打印100~200之间的素数 第五题&#xff1a;求斐波那契数的第N个数 斐波那契数的概念&#xff1a;前两个数相加等于第三…

Objective-C方法的声明实现及调用

1.无参数的方法 1)声明 a.位置&#xff1a;在interface括弧的外面 b.语法&#xff1a; - (返回值类型)方法名称; interface Person : NSObject -(void) run; end 2)实现 a.位置&#xff1a;在implementation中实现 b.语法&#xff1a;加大括弧将方法实现的代码写在大括孤之中 …

Unity Mask合批情况验证

1.首先是两个Mask完全重合的情况下 每张图片使用的image都来自同一个图集 发现彼此之间是没有合批的&#xff0c;但是每个Mask内部是实现了合批的 经过计算此种情况的visiableList&#xff1a;mask1&#xff0c;IM1&#xff0c;IM2&#xff0c;mask2&#xff0c;IM3&#xf…

NoSQL基本内容

第一章 NoSQL 1.1 什么是NoSQL NoSQL&#xff08;Not Only SQL&#xff09;即不仅仅是SQL&#xff0c;泛指非关系型的数据库&#xff0c;它可以作为关系型数据库的良好补充。随着互联网web2.0网站的兴起&#xff0c;非关系型的数据库现在成了一个极其热门的新领域&#xff0c;…

c# cad2016选择封闭多段线获取多段线面积

在C#中&#xff0c;如果你想要通过AutoCAD .NET API来选择封闭多段线内部的其他闭合多段线并计算它们各自的面积&#xff0c;可以遵循以下基本步骤&#xff1a; 1、加载AutoCAD库&#xff1a; 确保你的C#项目引用了Autodesk.AutoCAD.Interop和Autodesk.AutoCAD.Interop.Common…

Jmeter连接数据库报错Cannot load JDBC driver class‘com.mysql.jdbc.Driver’解决

问题产生: 我在用jmeter连接数据库查询我的接口是否添加数据成功时,结果树响应Cannot load JDBC driver class com.mysql.jdbc.Driver 产生原因: 1、连接数据库的用户密码等信息使用的变量我放在了下面,导致没有取到用户名密码IP等信息,导致连接失败 2、jmeter没有JDB…

《动手学深度学习(PyTorch版)》笔记4.7

Chapter4 Multilayer Perceptron 4.7 Forward/Backward Propagation and Computational Graphs 本节将通过一些基本的数学和计算图&#xff0c;深入探讨反向传播的细节。首先&#xff0c;我们将重点放在带权重衰减&#xff08; L 2 L_2 L2​正则化&#xff09;的单隐藏层多层…

opencv#33 边缘检测

边缘检测原理 图像的每一行每一列都可以看成是一个连续的信号经过离散后得到的数值&#xff0c;例如上图左侧给出的图像由黑色到白色的一个信号&#xff0c;也就是图像中某一行像素变化是由黑色逐渐到白色&#xff0c;我们将其对应在一个坐标轴中&#xff0c;将像素值的大小对应…

【Java基础】聊聊你不知道反射的那些事

在编程语言中&#xff0c;反射是一个绕不过的一个话题&#xff0c;反射、注解、动态代理是支撑框架运行的核心技术。 在Spring中&#xff0c;IOC利用反射实现&#xff0c;创建对象。AOP利用动态代理实现&#xff0c;实现切面编程&#xff0c;配置利用注解实现。所以继上一篇&am…

代码随想录算法训练营第32天 | 122.买卖股票的最佳时机II 55.跳跃游戏 45.跳跃游戏II

买卖股票的最佳时机II 贪心思路 要想使用贪心算法解决此问题&#xff0c;意识到利润是可分解的很关键。比如[1,2,3,4,5]这个输入&#xff0c;最大利润为第一天买入&#xff0c;第五天卖出。这等效于第一天买入&#xff0c;第二天卖出&#xff0c;第二天再买入。。。 prices[4]…

HCS-华为云Stack-FusionSphere

HCS-华为云Stack-FusionSphere FusionSphere是华为面向多行业客户推出的云操作系统解决方案。 FusionSphere基于开放的OpenStack架构&#xff0c;并针对企业云计算数据中心场景进行设计和优化&#xff0c;提供了强大的虚拟化功能和资源池管理能力、丰富的云基础服务组件和工具…

MYSQL基本查询(CURD:创建、读取、更新、删除)

文章目录 前言一、Create1.全列插入2.指定列插入3.插入否则更新4.替换 二、Retrieve1.SELECT列2.WHERE条件3.结果排序4.筛选分页结果 三、Update四、Delete1.删除数据2.截断表 五、插入查询结果六、聚合函数 前言 操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型…

kali系统入侵电脑windows(win11系统)渗透测试,骇入电脑教学

本次渗透测试将使用kali虚拟机&#xff08;攻击机&#xff09;对本机&#xff08;靶机&#xff09;进行入侵并监控屏幕 声明&#xff1a;本篇仅仅是将本机作为靶机的一次简易渗透测试&#xff0c;实际情况中基本不可能出现如此简单的木马骇入&#xff08;往往在上传木马时就被防…

Android App开发-简单控件(4)——按钮触控和图像显示

3.4 按钮触控 本节介绍了按钮控件的常见用法&#xff0c;包括&#xff1a;如何设置大小写属性与点击属性&#xff0c;如何响应按钮的点击事件和长按事件&#xff0c;如何禁用按钮又该如何启用按钮&#xff0c;等等。 3.4.1 按钮控件Button 除了文本视图之外&#xff0c;按钮…

clickhouse 安装与入门(单节点安装)

1、简介 Clickhouse 是一个开源的面向联机分析处理&#xff08;OLAP, On-Line Analytical Processing&#xff09;的列式存储数据库管理系统。写入快、查询快&#xff0c;支持sql向量化、并行和分布式查询&#xff1b;但是不支持事务&#xff0c;不支持二级索引等。由俄罗斯的Y…

5_机械臂运动学基础_矩阵

上次说的向量空间是为矩阵服务的。 1、学科回顾 从科技实践中来的数学问题无非分为两类&#xff1a;一类是线性问题&#xff0c;一类是非线性问题。线性问题是研究最久、理论最完善的&#xff1b;而非线性问题则可以在一定基础上转化为线性问题求解。 线性变换&#xff1a; 数域…

【jetson笔记】解决vscode远程调试qt.qpa.xcb: could not connect to display报错

配置x11转发 jetson远程安装x11转发 安装Xming Xming下载 安装完成后打开安装目录C:\Program Files (x86)\Xming 用记事本打开X0.hosts文件&#xff0c;添加jetson IP地址 后续IP改变需要重新修改配置文件 localhost 192.168.107.57打开Xlaunch Win菜单搜索Xlaundch打开 一…

openssl3.2 - 测试程序的学习 - test\acvp_test.c

文章目录 openssl3.2 - 测试程序的学习 - test\acvp_test.c概述笔记要单步学习的测试函数备注END openssl3.2 - 测试程序的学习 - test\acvp_test.c 概述 openssl3.2 - 测试程序的学习 将test*.c 收集起来后, 就不准备看makefile和make test的日志参考了. 按照收集的.c, 按照…