vue-router前端路由

前端路由

定义:在单页面应用中,前端对url自行管理,控制页面展示不同的内容或页面。
优点:用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点:
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义。前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求

后端路由

定义:通过用户请求的url导航到具体的html页面;每跳转到不同的URL,都是重新访问服务端,然后服务端返回页面,页面也可以是服务端获取数据,然后和模板组合,返回HTML,也可以是直接返回模板HTML,然后由前端js再去请求数据,使用前端模板和数据进行组合,生成想要的HTML

对比

1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。     
2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题。但是前端路由使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。

vue-router前端路由原理

前端路由主要模式:hash模式和history模式
而在vue-router中,它提供mode参数来决定采用哪一种方式,选择流程如下:
默认Hash–>如果浏览器支持History新特性改用History–>如果不在浏览器环境则使用abstract

方法1history模式:html5 history api

问题背景:解决ajax页面刷新,浏览器无法记住当前状态的问题。
解决思路:使用ajax的站点,在Ajax更新页面局部内容的同时,也在地址栏的URL里更新状态参数,就可以做出更完美的Ajax翻页
**

pushState(state,title,url),负责存储当前历史记录点。可以在不加载新页面的情况下改变浏览器URL。其中:

state:是一个状态对象,提供页面初始化所需要的各种信息,可以为空 title:null
url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
url是可选的,负责改变浏览器的地址栏中显示的url,如果没有指定url,你点击前进后退按钮页面还是会变化,只是浏览器的地址栏上显示的url会一直保持不变

// 假定当前网址是example.com/1.html
var json = {
  name:'Jack'
}
history.pushState(json,'','Jack.html');
// 运行结果是 当前网址变成example.com/Jack.html
// 同时 回退按钮出现

产生的结果:

  1. 在window.history里新增一个历史记录点。
  2. 不会发生服务器请求。
  3. 出现“前进”“后退”按钮,进而能够触发window.popstate事件(每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。)
  4. 绝不会导致hashchange 事件被激活

replaceState(state,title),负责替换当前历史记录点。
产生的结果

  1. 不产生历史记录
  2. 不会触发popState
  3. 适应场景:当你为了响应用户的某些操作,而要更新当前历史记录条目的状态对象或URL时

popState()
只有用户点击浏览器倒退按钮和前进按钮,或者使用JavaScript调用back、forward、go方法时才会触发;

该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。
事件监听:

window.onpopState = function() {
   // 当假定当前网址在example.com/Jack.html

    // 获得存储在该历史记录点的json对象
    var stateJson = window.history.state;
    // 点击一次回退到:example.com/Jack.html
    // 获得的json为{name:'Jack'}
    // 再点击一次前进到:example.com/1.html
    // 获得json为null  
}

另外一种获取状态对象的方法

window.onpopState = function(event) {
    // 获得存储在该历史记录点的json对象
    var stateJson = event.state;
}

其他history对象
后退:功能相当于回退按钮

window.history.back();
window.history.go(-1);

向前:

window.history.forward();
window.history.go(1);

获取history对象长度:

var len = window.history.length;

应用:实现ajax翻页

  • 首先,在服务器端添加对URL状态参数的支持(如?page=xxx),例如?page=3将会输出对应页码的内容(后端模板)。
  • 翻页时,给URL添加相page=xxx
var newUrl = "?page=" + pageNow;
history.pushState(null,"",newUrl);
// 解决F5刷新问题
  • 回退/前进按钮,更新页码数据
window.onpopState = function() {
   updateByPage(pageNow);
}

方法2hashm模式:vue-router mode:hash

地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。
如 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。可通过 window.location.hash 读取到的,读取到路径加以解析之后就可以响应不同路径的逻辑处理。
特点:
hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
即使没有做到对路由的全覆盖,也不会返回 404 错误。

为什么hash模式不会出现404问题 history模式会出现404
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式下,单页应用来讲,进入应用时加载index.html,后续在的网络操作通过Ajax完成,不会根据URL重新请求页面,但如用户直接在地址栏中输入并回车,浏览器重启重新加载应用,在此情况下重新向后端发送请求,如后端没有配置对应/user/id的路由处理,则会返回404错误。
官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,对于所有匹配不到的路径都会返回 index.html 文件。

history与hash两种模式的区别

  • URL:pushState设置的新URL可以是与当前URL同源的任意URL;而hash只可修改#后面的部分,故只可设置与当前同文档的URL
  • URL:pushState设置的新URL都会被添加到历史记录栈中;而hash设置的新值必须与原来不一样才会触发记录添加到栈
  • 添加的类型:pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串
  • pushState可额外设置title属性供后续使用

总结:

从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下):

  1. 记录当前页面的状态(保存或分享当前页的url,再次打开该url时,网页还是保存(分享)时的状态);
  2. 可以使用浏览器的前进后退功能(如点击后退按钮,可以使页面回到使用ajax更新页面之前的状态,url也回到之前的状态);

作为开发者,要实现这两个功能,我们需要做到:

  1. 改变url且不让浏览器向服务器发出请求;
  2. 监测 url 的变化;监测 url 的变化;
  3. 截获 url 地址,并解析出需要的信息来匹配路由规则。

我们路由常用的hash模式和history模式实际上就是实现了上面的功能。

参考链接:
https://www.cnblogs.com/historymemory/p/6393539.html
http://www.cnblogs.com/sniper007/p/3536157.html?utm_source=tuicool&utm_medium=referral
http://www.cnblogs.com/stephenykk/p/5057022.html

猜你喜欢

转载自blog.csdn.net/MingleHDU/article/details/84582158