vue-router路由模式详解(小结)


Posted in Javascript onAugust 26, 2019

一、路由模式解析

要讲vue-router的路由模式,首先要了解的一点就是路由是由多个URL组成的,使用不同的URL可以相应的导航到不同的位置。

如果有进行过服务器开发或者对http协议有所了解就会知道,浏览器中对页面的访问是无状态的,所以我们在切换不同的页面时都会重新进行请求。而实际使用vue和vue-router开发就会明白,在切换页面时是没有重新进行请求的,使用起来就好像页面是有状态的,这是什么原因呢。

这其实是借助了浏览器的History API来实现的,这样可以使得页面跳转而不刷新,页面的状态就被维持在浏览器中了。

vue-router中默认使用的是hash模式,也就是会出现如下的URL:vue-router路由模式详解(小结),URL中带有#号

我们可以用如下代码修改成history模式:

import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/components/Main'
Vue.use(Router)

export default new Router({
 mode: 'history',
 routes: [
 {
  path: '/',
  component: Main
 }
 ]
})

这样子URL中的#号就被去除了。

实际上存在三种模式:

Hash: 使用URL的hash值来作为路由。支持所有浏览器。

History: 以来HTML5 History API 和服务器配置。参考官网中HTML5 History模式

Abstract: 支持所有javascript运行模式。如果发现没有浏览器的API,路由会自动强制进入这个模式。

二、两种模式的区别

1、hash模式

hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件:

window.onhashchange = function(event){
 console.log(event.oldURL, event.newURL);
 let hash = location.hash.slice(1);
 document.body.style.color = hash;
}

上面的代码可以通过改变hash来改变页面字体颜色,虽然没什么用,但是一定程度上说明了原理。

更关键的一点是,因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来,后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配。

我们写个简单的方法来测试一下

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<body>
 <div>测试一下</div>
 <script type="text/javascript">
  window.onhashchange = function(event){
   console.log(event.oldURL,event.newURL)
   let hash = location.hash.slice(1);
   document.body.style.color = hash;
  }
 </script>
</body>
</html>

vue-router路由模式详解(小结)

vue-router路由模式详解(小结)

并且通过浏览器的前进、后退页面均可以变化。

网易云音乐,百度网盘就采用了hash路由,看起来就是这个样子:

http://music.163.com/#/friend
https://pan.baidu.com/disk/home#list/vmode=list

 2、history路由

随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由

history api可以分为两大部分:切换和修改

(1)切换历史状态

包括back、forwardgo三个方法,对应浏览器的前进,后退,跳转操作,有同学说了,(谷歌)浏览器只有前进和后退,没有跳转,嗯,在前进后退上长按鼠标,会出来所有当前窗口的历史记录,从而可以跳转(也许叫跳更合适):

history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进

(2)修改历史状态

包括了pushState、replaceState两个方法,这两个方法接收三个参数:stateObj,title,url

history.pushState({color:'red'}, 'red', 'red')

window.onpopstate = function(event){
 console.log(event.state)
 if(event.state && event.state.color === 'red'){
  document.body.style.color = 'red';
 }
}

history.back();

history.forward();

通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。

通过history api,我们丢掉了丑陋的#,但是它也有个毛病:

不怕前进,不怕后退,就怕刷新,f5,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的。

在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题。但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。

(3)popstate实现history路由拦截,监听页面返回事件

当活动历史记录条目更改时,将触发popstate事件。

1、如果被激活的历史记录条目是通过对 history.pushState() 的调用创建的,或者受到对 history.replaceState() 的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本。

2、需要注意的是调用 history.pushState() 或 history.replaceState() 用来在浏览历史中添加或修改记录,不会触发popstate事件;

只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back())

我们测试一下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<body>
 <div>测试一下</div>
 <script type="text/javascript">
  if (window.history && window.history.pushState) {
   window.onpopstate = function(event) {
    console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
    //window.history.go(1)
    //window.history.back()
   };
   
   //window.addEventListener("popstate", function(e) {
   // window.location = 'http://www.baidu.com';
   //}, false);
   
   !function() {
    var state = {
     title: "title",
     url: "#"
    };
    window.history.pushState(state, "title", "#");
   }();
  }
 </script>
</body>
</html>

刷新时不打印,刷新多次,再后退,每次都有,直到为null

vue-router路由模式详解(小结)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JAVASCRIPT IE 与 FF中兼容问题小结
Feb 18 Javascript
prototype 学习笔记整理
Jul 17 Javascript
简单的代码实现jquery定时器
Nov 17 Javascript
JS简单实现登陆验证附效果图
Nov 19 Javascript
Node.js 的异步 IO 性能探讨
Oct 08 Javascript
jQuery获取页面元素绝对与相对位置的方法
Jun 10 Javascript
Javascript自执行匿名函数(function() { })()的原理浅析
May 15 Javascript
jQuery原理系列-css选择器的简单实现
Jun 07 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
Aug 17 Javascript
jQuery实现动态控制页面元素的方法分析
Dec 20 jQuery
vue控制多行文字展开收起的实现示例
Oct 11 Javascript
针对Vue路由history模式下Nginx后台配置操作
Oct 22 Javascript
vue+moment实现倒计时效果
Aug 26 #Javascript
原生js实现针对Dom节点的CRUD操作示例
Aug 26 #Javascript
Moment.js实现多个同时倒计时
Aug 26 #Javascript
vue获取验证码倒计时组件
Aug 26 #Javascript
seajs和requirejs模块化简单案例分析
Aug 26 #Javascript
JavaScript实现身份证验证代码实例
Aug 26 #Javascript
基于vue、react实现倒计时效果
Aug 26 #Javascript
You might like
PHP通过COM使用ADODB的简单例子
2006/12/31 PHP
PHP5.2下chunk_split()函数整数溢出漏洞 分析
2007/06/06 PHP
php学习笔记之 函数声明
2011/06/09 PHP
那些年我们错过的魔术方法(Magic Methods)
2014/01/14 PHP
php文件上传类完整实例
2016/05/14 PHP
Thinkphp事务操作实例(推荐)
2017/04/01 PHP
浅析jQuery的链式调用之each函数
2010/12/03 Javascript
Js-$.extend扩展方法使方法参数更灵活
2013/01/15 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
2014/09/25 Javascript
详解使用nodeJs安装Vue-cli
2017/05/17 NodeJs
微信小程序实现人脸识别登陆的示例代码
2019/04/02 Javascript
浅谈vue项目,访问路径#号的问题
2020/08/14 Javascript
[38:39]KG vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
[01:33]PWL开团时刻DAY2-开雾与反开雾
2020/10/31 DOTA
Empty test suite.(PyCharm程序运行错误的解决方法)
2018/11/30 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
Python生成rsa密钥对操作示例
2019/04/26 Python
解决python replace函数替换无效问题
2020/01/18 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
pytorch 限制GPU使用效率详解(计算效率)
2020/06/27 Python
详解CSS3 弹性布局快速入门
2019/06/06 HTML / CSS
adidas澳大利亚官方网站:adidas Australia
2018/04/15 全球购物
英国旅行箱包和行李箱购物网站:Travel Luggage & Cabin Bags
2019/08/26 全球购物
用Python写一个for循环的例子
2016/07/19 面试题
优秀大学生推荐信范文
2013/11/28 职场文书
生物科学专业个人求职信范文
2013/12/05 职场文书
营销部内勤岗位职责
2014/04/30 职场文书
招商银行工作证明
2015/06/17 职场文书
大学运动会通讯稿
2015/07/18 职场文书
社区挂职锻炼个人工作总结
2015/10/23 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python
关于React Native使用axios进行网络请求的方法
2021/08/02 Javascript
基于PyQT5制作一个桌面摸鱼工具
2022/02/15 Python
Docker容器harbor私有仓库部署和管理
2022/08/05 Servers