Vue-Router 介绍及路由原理分析
文章目录
- Vue-Router 路由模式
- 单页面与传统页面跳转的区别
- Hash 模式
- History 模式
- abstract 模式
- 原理解析
- Hash 模式原理
- History 模式原理
- 路由使用
- 引入 Vue-Router
- 获取全局路由跳转参数的变化
- 获取路由中带的参数
- 重定向页面
Vue-Router 路由模式
单页面与传统页面跳转的区别
- 单页面
Vue 的单页面开发模式是基于组件和路由的配合,所有的页面均可视为组件,路由控制着访问路径,而每个路径映射一个组件。在单页模式中使用 a 标签做路由跳转是行不通的,因为本质上单页模式就只有一个 index.html 页面,所有的页面组件都在打包好的 JS 文件中,所以要使用 Vue-Router 的路由组件来跳转,这里的原因在后文中会有具体的例子解析。
- 传统页面
传统页面的开发模式,路由一般是由超链接(a 标签)来控制页面的跳转与切换,每次都会刷新整个页面,体验上不如单页模式。
Vue-Router 为我们提供了三种路由模式:
- Hash 模式
- History 模式
- abstract 模式
Hash 模式
Hash 模式是 Vue-Router 的默认模式,具体的体现是在浏览器地址栏上 URL 路径永远带着一个「#」号。在浏览器支持度上面,Hash 模式是比较强势的,甚至能兼容低版本的 IE 浏览器。「#」号后面内容的改变,不会引起页面对服务端的请求,所以也就不会重新加载页面。在部署服务器方面,个人认为 Hash 模式比 History 模式来得更为方便,因为 History 有 URL 重定向问题,需要在服务端去配置 url 重定向,否则会报 404 错误。市面上也有不少大厂是使用 Hash 模式进行开发的,比如网易云音乐:
History 模式
HTML5 History API 提供了一个 history.pushState 和 history.reolaceState 方法(浏览器支持情况不是很乐观),它能让开发人员在不刷新网页的情况下改变站点的 URL。因为 Hash 模式会带上一个「#」号,会让 URL 地址变得比较难看,所以很多开发者都会选择 History 模式开发。但有个缺点,前端的 URL 必须和实际向服务端发起的请求的 URL 保持一致,如果服务端没有对相应的路由做处理,则会返回 404 错误页面。
abstract 模式
abstract 模式针对的是没有浏览器环境的情况,比如 Weex 客户端开发,内部是没有浏览器 API 的,那么 Vue-Router 自身会对环境做校验,强制切换到 abstract 模式,如果默认在 Vue-Router 的配置项中不写 mode 的值,在浏览器环境下会默认启用 Hash 模式,在移动客户端下使用 abstract 模式。
原理解析
Hash 模式原理
大家常常会在浏览器上看到这样一种场景,点击某个文字,网页会跳转到某一个固定的位置,并且页面不会刷新。这便是浏览器的 a 标签锚点。Hash 模式被运用在了单页面开发的路由模式上,下面我们来简单实现一个通过 Hash 去控制页面组件的展示。 浏览器原生方法为我们提供了一个监听事件 hashchange
,它能监听到的改变如下:
- 点击 a 标签改变 URL 地址;
- 浏览器的前进后退行为;
- 通过
window.location
方法改变地址栏。
以上三种情况都会触发 hashchange
监听事件,通过这个事件我们可以获取到 localtion.hash
,继而去匹配相应的组件,下面是简易代码实现:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Hash 模式</title></head><body><div><ul><li><a href="#/page1">page1</a></li><li><a href="#/page2">page2</a></li></ul><div id="route-view"></div></div><script type="text/javascript">// 下面为hash的路由实现方式// 第一次加载的时候,不会执行hashchange监听事件,默认执行一次window.addEventListener('DOMContentLoaded', Load);window.addEventListener('hashchange', HashChange);var routeView = null;function Load() {routeView = document.getElementById('route-view');HashChange();}function HashChange() {console.log('location.hash', location.hash);switch (location.hash) {case '#/page1':routeView.innerHTML = 'page1';return;case '#/page2':routeView.innerHTML = 'page2';return;default:routeView.innerHTML = 'page1';return;}}</script></body>
</html>
当初始的 HTML 文档被完全加载和解析完成之后, DOMContentLoaded
事件被触发,而无需等待样式表、图像和子框架的完成加载。 hashchange
不会被默认触发,所以网页首次加载完成后,需要默认执行一次 hashchange
监听方法要执行的函数 HashChange
,当我点击代码中的两个 a 标签时,URL 地址栏改变触发 hashchange
事件, HashChange
方法通过拿到 location.hash
去匹配相应的组件(这里假设 page1、page2 为页面容器组件)。
在浏览器中打开HTML查看效果:
这样我们就实现了一个简易版的 Hash 路由模式,大家可以自己手动实现一下,加深记忆。
History 模式原理
下面来介绍 History 模式。
通过 History 模式去控制路由,会遇到一些麻烦,根本原因是 History 模式利用的时候 popstate
监听事件无法监听到 pushState
、 replaceState
、a 标签这三种形式的变化,浏览器的前进后退是可以监听到。那么有什么好的解决方案吗?
小知识:pushState 和 replaceState 都是 HTML5 的新 API,他们的作用很大,可以做到改变浏览器地址却不刷新页面。
我们可以通过遍历页面上的所有 a 标签,阻止 a 标签的默认事件的同时,加上点击事件的回调函数,在回调函数内获取 a 标签的 href 属性值,再通过 pushState
去改变浏览器的 location.pathname
属性值。然后手动执行 popstate
事件的回调函数,去匹配相应的路由。逻辑上可能有些饶,我们用代码来解释一下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>History 模式</title></head><body><div><ul><li><a href="/page1">page1</a></li><li><a href="/page2">page2</a></li></ul><div id="route-view"></div></div><script type="text/javascript">// 下面为history的路由实现方式window.addEventListener('DOMContentLoaded', Load);window.addEventListener('popstate', PopChange);var routeView = null;function Load() {routeView = document.getElementById('route-view');PopChange();// 获取所有带 href 属性的 a 标签节点var aList = document.querySelectorAll('a[href]');// 遍历 a 标签节点数组,阻止默认事件,添加点击事件回调函数aList.forEach((aNode) =>aNode.addEventListener('click', function (e) {e.preventDefault(); //阻止a标签的默认事件var href = aNode.getAttribute('href');// 手动修改浏览器的地址栏history.pushState(null, '', href);// 通过 history.pushState 手动修改地址栏,// popstate 是监听不到地址栏的变化,所以此处需要手动执行回调函数 PopChangePopChange();}));}function PopChange() {console.log('location', location);switch (location.pathname) {case '/page1':routeView.innerHTML = 'page1';return;case '/page2':routeView.innerHTML = 'page2';return;default:routeView.innerHTML = 'page1';return;}}</script></body>
</html>
同样将上面代码复制到 index.js 文件下替换,效果如下所示:
这就是我们上述提到的 History 模式下,会遇到的麻烦。想要解决这个问题需要配合项目的 Web 服务器如 Express、Koa 等配置服务端返回的内容。
路由使用
接下来我们采用 ES2015 的形式简单讲解 Vue Router 的使用。
引入 Vue-Router
首先是 HTML,我们引入 Vue 和 Vue Router 的静态资源,大家可以去 BootCDN 搜索自己需要的静态资源,下面是 HTML 代码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script><script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script><title>Vue Router</title></head><body><div id="app"><ul><!-- 使用 router-link 组件来导航. --><!-- 通过传入 to 属性指定链接. --><!-- <router-link> 默认会被渲染成一个 <a> 标签 --><router-link to="/page1">Go to Page1</router-link><br /><router-link to="/page2">Go to Page2</router-link></ul><!-- 路由出口 --><!-- 路由匹配到的组件将渲染在这里 --><router-view></router-view></div><script type="text/javascript">// 1. 定义 (路由) 组件。// 可以从其他文件 import 进来,这里简单写const Page1 = { template: '<div>Page1</div>' };const Page2 = { template: '<div>Page2</div>' };// 2. 定义路由// 每个路由应该映射一个组件。 其中"component" 可以是// 通过 Vue.extend() 创建的组件构造器,// 或者,只是一个组件配置对象。const routes = [{ path: '/page1', component: Page1 },{ path: '/page2', component: Page2 },];// 3. 创建 router 实例,然后传 routes 配置// 你还可以传别的配置参数, 不过先这么简单着吧。const router = new VueRouter({routes: routes,});// 4. 创建和挂载根实例。// 记得要通过 router 配置参数注入路由,// 从而让整个应用都有路由功能const app = new Vue({router: router,}).$mount('#app');</script></body>
</html>
标签和 标签是引入 Vue-Router 后才能使用的,路由匹配到的组件都会渲染在 标签上, 标签用于路由的跳转。
Vue-Router 默认启动 Hash 模式,同样复制到 index.js,重启 node app.js 启动页面的时候,会看到如下所示:
获取全局路由跳转参数的变化
想要全局监听路由的变化,可以在入口页面通过 watch $router
对象来实现,修改上述代码:
<script>...
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能。
const app = new Vue({router: router,watch: {$route(to, from) {console.log('to', to)console.log('from', from)}}
}).$mount('#app')...
</script>
添加监听之后,可以拿到 to 和 from 两个参数,to 代表你跳转后的页面参数,from 代表你从哪个页面跳转来的,通过拿到这两个参数,我们就能设置一级二级页面,用于制作过场动画。也可以添加页面顶部的页面加载进度条。
获取路由中带的参数
Page1 页面在跳转的时候带上参数到 Page2,我们如何在 Page2 拿到参数呢?首先我们要给 router-link
标签添加参数,如下所示:
<router-link :to="{path: '/page1', query: { id: 1111 }}">Go to Page1
</router-link>
在 Page1 的模板页面拿到参数:
const Page1 = { template: '<div>Page1 {{ $route.query.id }}</div>' };
重定向页面
这点还是比较重要的,当你输入一个不存在的路由,Vue-Router 无法匹配到的时候,需要默认回到首页,这就要用到重定向匹配,代码如下所示:
const routes = [{ path: '/page1', component: Page1 },{ path: '/page2', component: Page2 },{ path: '*', redirect: '/page1' },
];
这里我们默认 Page1 为首页,当 *
上面的路径都没有被匹配到的时候,就会重新回到 /page1
对应的组件。
以上是 Vue-Router 的一些基础用法,更多深度使用请移步 官方文档详细阅读。
相关文章:
Vue-Router 介绍及路由原理分析
文章目录Vue-Router 路由模式单页面与传统页面跳转的区别Hash 模式History 模式abstract 模式原理解析Hash 模式原理History 模式原理路由使用引入 Vue-Router获取全局路由跳转参数的变化获取路由中带的参数重定向页面Vue-Router 路由模式 单页面与传统页面跳转的区别 单页面…...
git代码提交后jenkins构建和自动部署
利用jenkins和gitlab的webhook结合,实现提交代码之后,自动触发jenkins的构建。顺带介绍一下通过触发器构建,比如直接通过url去触发的方式。 一、jenkins结合webhook 1、jenkins配置 a、首先jenkins得需要安装两个gitlab的插件:(…...
2023面试题目总结
项目遇到的问题难点? 老项目版本过低(angular4),相关框架太少,需要升级成新框架。 1.single-spa 2.qiankun 3.iframe 样式环境隔离/js隔离/公共依赖的加载 JS 原型,原型链,new 原型是存放公共属性地方,所有实例都…...
Vue常用指令及声明周期
文章目录知识点前端开发环境配置v-text && v-htmlv-if、v-else && v-showv-forv-onv-modelv-bind、v-cloak、v-pre&&v-once全局 API 是什么Vue.directive 自定义组件Vue.directive 是什么自定义组件回调函数参数自定义组件的生命周期Vue.set 全局操作为…...
MariaDB 成功敲钟上市 | 它与 Navciat 缘起 10 年前
MariaDB 敲钟上市2022 年底,云数据库公司 MariaDB 与 Angel Pond Holdings 公司完成合并,并在纽交所上市。新公司更名为 MariaDB,MySQL 之父奋斗了13年终敲钟。这标志着 MariaDB 开启新篇章。无论从开源还是商业之路,都将成为业内…...
LESS模型与随机森林
模型学习 1 随机森林 https://blog.csdn.net/weixin_35770067/article/details/107346591? 森林就是建立了很多决策树,把很多决策树组合到一起就是森林。 这些决策树都是为了解决同一任务建立的,最终的目标也都是一致的,最后将其结果来平均…...
如何利用Power Virtual Agents机器人实现成绩查询服务
今天我们继续介绍如何利用Power Virtual Agents来实现成绩查询服务。设计思路是在PVA聊天机器人的对话框中输入学生的姓名和学号来进行成绩的查询。首先,在Microsoft 365的OneDrive中制作一个Excel格式的成绩单。 可以将学生的学号、姓名、各学科成绩进行添加。 在P…...
flavor 配置
文章目录1. flavorDimensions1.1 单维度1.2 多维度2. BuildConfig3. sourceSets4. 参考资料1. flavorDimensions 与 productFlavors 配合使用使用 flavorDimensions 定义风味维度,维度越多,能打出的渠道包越丰富 1.1 单维度 defaultConfig {...flavor…...
《第一行代码》 第五章:详解广播机制
如果你了解网络通信原理应该会知道,在一个 IP 网络范围中最大的IP 地址是被保留作为广播地址来使用的。比如某个网络的 IP 范围是 192.168.0XXX,子网掩码是255.255.255.0那么这个网络的广播地址就是 192.168.0255广播数据包会被发送到同-网络上的所有端口…...
Leetcode(每日一题)——1139. 最大的以 1 为边界的正方形
摘要 1139. 最大的以 1 为边界的正方形 一、以1为边界的最大正方形 1.1 动态规划 第530题需要正方形所有网格中的数字都是1,只要搞懂动态规划的原理,代码就非常简洁。而这题只要正方形4条边的网格都是1即可,中间是什么数字不用管。 这题…...
YOLOv5:GitHub两万八Star项目
来源:投稿 作者:王同学 编辑:学姐 Yolov5详解 官方源码仓库:https://github.com/ultralytics/yolov5 相关论文:未发表(改进点都被你们抢先发了) 0 前言 截止到2022年7月,Yolov5项…...
袋鼠云产品功能更新报告04期丨2023年首次,产品升级“狂飙”
新的一年我们加紧了更新迭代的速度,增加了数据湖平台EasyLake和大数据基础平台EasyMR,超40项功能升级优化。我们将继续保持产品升级节奏,满足不同行业用户的更多需求,为用户带来极致的产品使用体验。 以下为袋鼠云产品功能更新报…...
如何在Power Virtual Agents中使用Power Automate
今天我们来介绍一下如何在Power Virtual Agents中使用PowerAutomate。我们以通过在PVA聊天机器人的对话框中输入“发布通知”后会把预设好的通知信息自动发布到Teams中的某个团队中为例。首先进入PVA聊天机器人编辑界面后选择“主题”-“新建主题”。 在“新建主题”中添加“触…...
BXC6332A第二代智能头盔方案助力电动车市场,为安全保驾护航
随着2020年6月1日起,公安部交管局在全国开展“一盔一带”安全守护行动,摩托车、电动车驾驶人乘车人按照规定正确使用头盔,是保障司乘安全的一道重要屏障,据统计,摩托车、电动自行车驾乘人员死亡事故中约80%为颅脑损伤致…...
浮点数值计算精度丢失问题剖析及解决方法
文章目录1、原因分析2、解决方法2.1、Java中使用 BigDecimal 类2.2、JavaScript 中解决计算精度丢失的问题3、使用建议1、原因分析 首先我们来看个反直觉的浮点数值计算 System.out.println(0.3*3);有的同学可能要问为啥不是0.9? 首先要知道为什么会产生这个问题…...
字符串匹配 - 模式预处理:朴素算法(Naive)(暴力破解)
朴素的字符串匹配算法又称为暴力匹配算法(Brute Force Algorithm),最为简单的字符串匹配算法。算法简介朴素的字符串匹配算法又称为暴力匹配算法(Brute Force Algorithm),它的主要特点是:没有预…...
CVE-2021-42278 CVE-2021-42287域内提权漏洞
漏洞介绍2021 年 11 月 9 日,国外研究员在推特上发布了AD相关的 CVE,CVE-2021-42278 & CVE-2021-42287 ,两个漏洞组合可导致域内普通用户权限提升至域管权限。CVE-2021-42278:是一个安全绕过漏洞,允许通过修改机器…...
关于IcmpSendEcho2的使用和回调问题
由于我的需求是短时间内ping多台机子,所以需要异步执行,微软提供的例子是同步方式的,根据微软官方提供的icmpSendEcho2 函数的信息 ,我需要定义一个空的宏PIO_APC_ROUTINE_DEFINED ,定义完之后,编译又出现…...
XQuery 术语
在 XQuery 中,有七种节点:元素、属性、文本、命名空间、处理指令、注释、以及文档节点(或称为根节点)。 XQuery 术语 节点 在 XQuery 中,有七种节点:元素、属性、文本、命名空间、处理指令、注释、以及文…...
会议论文分享-Security22-状态感知符号执行
Ferry: State-Aware Symbolic Execution for Exploring State-Dependent Program Paths1.引言2.问题陈述与分析2.1.实现状态感知符号执行的挑战2.2.真实程序的特征2.3.Ferry的模型2.3.1.程序状态的定义2.3.2.状态描述变量的特征3.Design3.1.Overview of Ferry3.2.状态描述变量识…...
吴恩达深度学习笔记(八)——卷积神经网络(上)
一、卷积相关 用一个ff的过滤器卷积一个nn的图像,假如padding为p,步幅为s,输出大小则为: [n2p−fs1][n2p−fs1][\frac{n2p-f}{s}1][\frac{n2p-f}{s}1][sn2p−f1][sn2p−f1] []表示向下取整(floor) 大部分深度学习…...
14 基数排序(桶排序)
文章目录1 基数排序基本思想2 基数排序的代码实现2.1 java2.2 scala3 基数排序总结1 基数排序基本思想 1) 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort&#…...
汉明距离Java解法
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y,计算并返回它们之间的汉明距离。 例: 输入:x 1, y 4 输出:2 解释: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ 上…...
Netty服务端请求接受过程源码剖析
目标 服务器启动后,客户端进行连接,服务器端此时要接受客户端请求,并且返回给客户端想要的请求,下面我们的目标就是分析Netty 服务器端启动后是怎么接受到客户端请求的。我们的代码依然与上一篇中用同一个demo, 用io.…...
金三银四春招特供|高质量面试攻略
🔰 全文字数 : 1万5千 🕒 阅读时长 : 20min 📋 关键词 : 求职规划、面试准备、面试技巧、谈薪职级 👉 公众号 : 大摩羯先生 本篇来聊聊一个老生常谈的话题————“面试”。利用近三周工作午休时间整理了这篇洋洋洒洒却饱含真诚…...
搭建Hexo博客-第4章-绑定自定义域名
搭建Hexo博客-第4章-绑定自定义域名 搭建Hexo博客-第4章-绑定自定义域名 搭建Hexo博客-第4章-绑定自定义域名 在这一篇文章中,我将会介绍如何给博客绑定你自己的域名。其实绑定域名本应该很简单的,但我当初在这上走了不少弯路,所以我觉得有…...
lightdb-sql拦截
文章目录LightDB - sql 审核拦截一 简介二 参数2.1 lightdb_sql_mode2.2 lt_firewall.lightdb_business_time三 规则介绍及使用3.1 select_without_where3.1.1 案例3.2 update_without_where/delete_without_where3.2.1 案例3.3 high_risk_ddl3.3.1 案例LightDB - sql 审核拦截…...
二进制中1的个数-剑指Offer-java位运算
一、题目描述编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 1 的个数(也被称为 汉明重量).)。提示:请注意,在某些语言(如 Java&…...
学自动化测试可以用这几个练手项目
练手项目的业务逻辑比较简单,只适合练手,不能代替真实项目。 学习自动化测试最难的是没有合适的项目练习。 测试本身既要讲究科学,又有艺术成分,单单学几个 api 的调用很难应付工作中具体的问题。 你得知道什么场景下需要添加显…...
2023年保健饮品行业分析:市场规模不断攀升,年度销额增长近140%
随着人们健康意识的不断增强,我国保健品市场需求持续增长,同时,保健饮品的市场规模也在不断攀升。 根据鲸参谋电商数据显示,2022年度,京东平台上保健饮品的年度销量超60万件,同比增长了约124%;该…...
网站怎么做数据备份/广州网站建设方案维护
通过Web.config实现301重定向 IIS7以上可以通过修改Web.config实现IIS设置 现在我们通过Web.config实现301重定向 <system.webServer><validation validateIntegratedModeConfiguration"false" /><modules runAllManagedModulesForAllRequests"t…...
网站建设找d云世家/什么软件可以发帖子做推广
今天在看S3C2440开发板的初始化代码时,对#define A (* (volatile unsigned long *) 0x48000000这种形式的定义方式有困惑,于是求助GOOGLE大神,在网上搜到了一些文章,觉得以下三篇文章对理解这个有些作用: 文章一: 有关…...
外贸网络推广是什么/搜索引擎优化举例说明
01-Node.js介绍 前言 Node 的重要性已经不言而喻,很多互联网公司都已经有大量的高性能系统运行在 Node 之上。Node 凭借其单线程、异步等举措实现了极高的性能基准。此外,目前最为流行的 Web 开发模式是前后端分离的形式,即前端开发者与后端开发者在自己喜欢的 IDE 上独立…...
WordPress评论通知邮箱/关键词优化的软件
目录 auto_ptr 构造函数 拷贝赋值 让auto_ptr对象具有指针的行为 析构函数 unique_ptr _Unique_ptr_base remove_reference _Get_deleter_pointer_type _Unique_ptr_base的第三个模板参数 构造函数 无参/NULL构造 用管理对象实例构造 用管理对象实例及删除器实例…...
威海网站推广/百度竞价托管代运营公司
以下内容均为个人学习过程的总结记录,如有错误,望各位大佬指正~是什么Asynchronous JavaScript And XML,异步JS和XML:在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术(在等待服务器响应…...
手机app与网站链接/网络营销活动策划方案
元字符 . 除了换行符以外的任意一个字符 \w 匹配数字字母下划线 \s 匹配空白符 \d 匹配数字 \n 匹配换行符 \t 制表符^ 匹配字符串的开始 $ 匹配字符串的结束\W 匹配非字母或数字或下划线 \D 非数字 \S 非空白a|b 匹配字符a或者b () 匹配括号的表达式 [...] 匹配字符组中的字符…...