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.hqwc.cn/news/434443.html

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

相关文章

Mybatis-Plus入门

Mybatis-Plus入门 MyBatis-Plus 官网&#xff1a;https://mp.baomidou.com/ 1、简介 MyBatis-Plus (简称 MP) 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、 提高效率而生。 https://github.com/baomidou/mybatis-p…

数字图像处理(实践篇)三十一 Raw图像数据转为RGB图像实践

目录 1 Raw图像和RGB图像 2 Raw图像的排布方式 3 方案 4 实践 5 其他 1 Raw图像和RGB图像 Raw图片是未经压缩的,没有任何数据损失,Raw图片保留了从图像传感器捕获的每个像素的原始信息,因此可以实现更高的图像质量。

CC++内存管理【非常详细,对新手友好】

文章目录 一、程序内存划分1.基础知识2. 堆栈的区别3. 题目练手 二、C语言中动态内存管理方式三、C中动态内存管理方式1. new/delete操作内置类型2. new/delete操作自定义类型 四、operator new和operator delete函数1. 汇编查看编译器底层调用2. 透过源码分析两个全局函数 五、…

husky结合commitlint审查commit信息

commintlint是一个npm包用来规范化我们的commit信息&#xff0c;当然这个行为的操作时期是在git的commit-msg生命周期期间&#xff0c;这一点当然是有husky来控制&#xff0c;需要注意的是commit-msg作为一个git生命周期会被git commit和git merge行为唤醒&#xff0c;并且可以…

2023年五大顶流国漫公司揭秘:谁是最强王者?

各位动漫迷们&#xff0c;是不是觉得2023年的国漫界特别热闹&#xff1f;没错&#xff0c;经过一年激烈的角逐&#xff0c;国漫界涌现出了五大在制作数量和质量上都遥遥领先的顶流公司&#xff0c;他们各怀绝技&#xff0c;各有千秋&#xff0c;让整个国漫界都热闹非凡&#xf…

防御实验(安全策略,用户认证,NAT综合)

目录 步骤一&#xff1a;了解前提&#xff1a; 1.1 题目要求&#xff1a; 1.2 拓扑搭建&#xff0c;IP地址规划。 步骤二&#xff1a;二层配置 2.1 配置IP地址 2.2 valn配置 步骤三&#xff1a;三层的配置&#xff08;防火墙配置&#xff09; 3.1 IP地址配置 3.2 云配…

【数学建模美赛资料更新】往届数学建模竞赛成品论文分享/2024美赛成品论文预定

数学建模美赛&#xff1a;今天更新的是【2024美赛赛题翻译参考思路代码 成品论文】预定。上述材料才美赛比赛过程中都是限量发放&#xff0c;每个题目大概300~500份哦&#xff0c;所以需要同学们提前预定&#xff0c;先到先得哟~ 在这里奉上数模加油站在往期【数维杯国际赛、m…

【前端web入门第二天】01 html语法实现列表与表格

html语法实现列表与表格 文章目录: 1.列表 1.1 无序列表1.2 有序列表1.3 定义列表 2.表格 2.1 表格基本结构2.2 表格结构标签 写在最前,第二天学习目标: 列表 表格 表单 元素为嵌套关系 1.列表 作用:布局内容排列整齐的区域。 列表分类:无序列表、有序列表、定义列表。 1…

[Vulnhub靶机] DC-1

[Vulnhub靶机] DC-1靶机渗透思路及方法&#xff08;个人分享&#xff09; 靶机下载地址&#xff1a; https://download.vulnhub.com/dc/DC-1.zip 靶机地址&#xff1a;192.168.67.28 攻击机地址&#xff1a;192.168.67.3 一、信息收集 1.使用 arp-scan 命令扫描网段内存活的…

【Leetcode】2865. 美丽塔 I

文章目录 题目思路代码结果 题目 题目链接 给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i &#xff0c;高度为 heights[i] 。 如果以下条件满足&#xff0c;我们称这些塔是 美丽 的&#xff1a; 1 < hei…

带延迟的随机逼近方案(Stochastic approximation schemes):在网络和机器学习中的应用

1. 并行队列系统中的动态定价Dynamic pricing 1.1 系统的表述 一个含有并行队列的动态定价系统&#xff0c;该系统中对于每个队列有一个入口收费(entry charge) &#xff0c;且系统运行的目标是保持队列长度接近于某个理想的配置。 这里是这个系统的几个关键假设&#xff1a;…

[数据结构]-哈希

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 本期学习目标&…