单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面,

实现这一点主要是两种方式:

1.Hash: 通过改变hash值

2.History: 利用history对象新特性(详情可出门左拐见: http://www.cnblogs.com/yanze/p/7641774.html)

而在vue-router中,它提供mode参数来决定采用哪一种方式,选择流程如下:

默认Hash–>如果浏览器支持History新特性改用History–>如果不在浏览器环境则使用abstract

选好mode后创建history对象(HashHistory或HTML5History或AbstractHistory)

Hash

1.push() 设置新的路由添加历史记录并更新视图,常用情况是直接点击切换视图

调用流程:

(1) $router.push() //显式调用方法

(2) HashHistory.push() //根据hash模式调用,设置hash并添加到浏览器历史记录(window.location.hash= XXX)

(3) History.transitionTo() //开始更新

(4) History.updateRoute() //更新路由

(5) {app._route= route}

(6) vm.render() //更新视图

2.replace

功能: 替换当前路由并更新视图,常用情况是地址栏直接输入新地址

流程与push基本一致

但流程2变为替换当前hash (window.location.replace= XXX)

3.监听地址栏变化

在setupListeners中监听hash变化(window.onhashchange)并调用replace

History

1.push

与hash模式类似,只是将window.hash改为history.pushState

2.replace

与hash模式类似,只是将window.replace改为history.replaceState

3.监听地址变化

在HTML5History的构造函数中监听popState(window.onpopstate)

两种模式对比

History模式的优点:

1.History模式的地址栏更美观。

2.History模式的pushState、replaceState参数中的新URL可为同源的任意URL(可为不同的html文件),而hash只能是同一文档

3.History模式的pushState、replaceState参数中的state可为js对象,能携带更多数据

4.History模式的pushState、replaceState参数中的title能携带字符串数据(当然,部分浏览器,例如firefox不支持title,一般title设为null,不建议使用)

缺点:

对于单页面应用来说,理想的场景是仅仅在进入应用时加载页面(例如index.html),后续的网络操作靠ajax完成,

而不会重新请求页面。

但当用户直接在用户栏输入地址时则会重新请求,当地址带有参数时两者情况不一样

Hash 例如: xxx.com/#/id=5 HTTP请求不会包含后面的hash值,所以请求的仍然是 xxx.com,没有问题

History 例如: xxx.com/id=5 这时请求的便是xxx.com/id=5,如后端没有配置对应id=XXX的路由处理,则会返回404错误。

官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。同时这么做以后,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。或者,如果是用 Node.js 作后台,可以使用服务端的路由来匹配 URL,当没有匹配到路由的时候返回 404,从而实现 fallback。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue路由原理</title>
<style media="screen" type="text/css">
*{margin:0;padding:0;}
li{list-style:none;}
#app{width:450px;margin:0 auto;}
.nav{overflow:hidden;}
.nav li{float:left;margin: 10px;}
</style>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="app">
<ul class="nav">
<li v-for="item in types"><a :href="'#/'+item.link">{{item.title}}</a></li>
</ul>
<component v-bind:is="show"></component>
</div> <script type="text/javascript">
Vue.component('zy',{
template:'<h2>这是主页</h2>'
})
Vue.component('rz',{
template:'<h2>这是日志</h2>'
})
Vue.component('xc',{
template:'<h2>这是相册</h2>'
})
var app=new Vue({
'el':'#app',
data:{
types:[
{title:'主页',link:'zy'},
{title:'日志',link:'rz'},
{title:'相册',link:'xc'}
],
show:'zy'
}
})
//自定义路由,vue没有提供路由方法
function router(){
//window.location.href和window.location.hash的区别
//window.location.href 获取完整的url
//window.location.hash 获取锚链接,相比如href,通过window.location.hash并不会跳转到新的链接,只会在当前链接里面改变锚链
var str=location.hash;
console.log(str); str=str.slice(1);
str=str.replace(/^\//,'');
//获取 # 后面的值
var map={
'zy':true,
'rz':true,
'xc':true
};
if(map[str]){
app.show=str;
}
else{
app.show='zy';
}
}
window.addEventListener("load",router);
//当hash 值改变的时候,监听hashchange事件
window.addEventListener("hashchange",router);
</script>
</body>
</html>

源码地址: https://github.com/zuobaiquan/js-principle-analysis/blob/master/vue路由原理/index.html

vue路由原理剖析的更多相关文章

  1. 浅谈vue路由原理

    Vue的路由实现:hash模式 和 history模式 hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取: 特点:hash虽然在UR ...

  2. C#进阶系列——WebApi 路由机制剖析:你准备好了吗?

    前言:从MVC到WebApi,路由机制一直是伴随着这些技术的一个重要组成部分. 它可以很简单:如果你仅仅只需要会用一些简单的路由,如/Home/Index,那么你只需要配置一个默认路由就能简单搞定: ...

  3. ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)

    ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...

  4. ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行

    ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行 核心框架 ASP.NET Core APP 创建与运行 总结 之前两篇文章简析.NET Core 以及与 .NET Framew ...

  5. ASP.NET Core 运行原理剖析

    1. ASP.NET Core 运行原理剖析 1.1. 概述 1.2. 文件配置 1.2.1. Starup文件配置 Configure ConfigureServices 1.2.2. appset ...

  6. Vue路由学习心得

    GoodBoy and GoodGirl~进来了就看完点个赞再离开,写了这么多也不容易的~ 一.介绍  1.概念:路由其实就是指向的意思,当我们点击home按钮时,页面中就要显示home的内容,点击l ...

  7. 开源 serverless 产品原理剖析 - Kubeless

    背景 Serverless 架构的出现让开发者不用过多地考虑传统的服务器采购.硬件运维.网络拓扑.资源扩容等问题,可以将更多的精力放在业务的拓展和创新上. 随着 serverless 概念的深入人心, ...

  8. ARouter原理剖析及手动实现

    ARouter原理剖析及手动实现 前言 路由跳转在项目中用了一段时间了,最近对Android中的ARouter路由原理也是研究了一番,于是就给大家分享一下自己的心得体会,并教大家如何实现一款简易的路由 ...

  9. vue-router路由原理

    Vue-router路由原理 目前实现路由的方式有两中,vue通过参数mode来设置,默认是hash模式. 利用URL中的hash(‘#’)来实现 利用History interface在HTML5中 ...

随机推荐

  1. Python之操作MySQL数据库

      一.操作步骤 1.导入pymysql模块 2.建立连接(ip.用户名.密码.数据库名.端口号.字符集.(自动提交参数)) 3.建立游标 4.执行sql语句 (4.需要提交的提交) 5.关闭游标 6 ...

  2. 学习PHPExcel

    关于PHPExcel使用方法,可以参考慕课网的教程,链接在此 PHPExcel的github地址:https://github.com/PHPOffice/PHPExcel 下载之后,将文件夹中的Cl ...

  3. O(N) 求数组中最大子串和

    int MaxSubSum3(int *arr, int len) { int i; long long MaxSum = 0; long long CurSum = 0; for(int i = 0 ...

  4. css中如何做到容器按比例缩放

    需求: 一般在响应式中,我们会要求视频的宽高比为16:9或4:3,这么一来就比较头大了.当用户改变浏览器宽度的时候(改变高度不考虑),视频的宽度变了,那么高度也得根据我们要求的16:9或4:3改变. ...

  5. php trait使用

    trait类似于基类  同样的方法优先级为 本类>trait>基类 <?php /** * Created by PhpStorm. * User: mac * Date: 2019 ...

  6. BPM与OA的区别

    近年来,随着计算机技术的发展和互联网时代的到来,我们已经进入了信息时代,也称为数字化时代,在这数字化的时代里,企业的经营管理都受到了极大的挑战.从上世纪90年代起至今,企业的信息化工作开展的如火如荼, ...

  7. python设计模式第十天【观察者模式】

    1.应用场景 (1)监听事件驱动程序中的外部事件 (2)监听某个对象的状态变化 (3)发布-订阅模型中,消息出现时通知邮件列表中的订阅者 2. 观察者模式UML图 3. 代码实现: #!/usr/bi ...

  8. QTP自动化测试-笔记 注释、大小写

    1 rem 注释内容 2 ' 注释内容 3 快捷键注释-选择代码行-ctrl+M 4 ctrl+shift+同- 取消注释 大小写 qtp:对小写敏感:如果 变量.sheet页是用小写字母命名,则使用 ...

  9. css多列居中

    https://jingyan.baidu.com/article/36d6ed1f67d58f1bcf488393.html

  10. jQuery方法区别:click() bind() live() delegate()区别

    今天看到一篇jquery 事件的文章,自己写了个小例子,虽然2种方式都可以实现,但是不太明白,找了点资料 $("#box1").delegate("p",&qu ...