浅谈前端路由🏃

什么是路由👻

当提到路由的时候你会想到什么? 路由器?简单来讲,路由就是URL到函数的映射前端

路由这个概念最早是后端出现的vue

  • 早期的网站开发的全部页面都是由服务器来进行渲染的,服务器直接生产渲染好的HTML页面返回给客户端显示
  • 一个页面有本身对应的URL,当你输入URL的时候会将这个URL发送到服务器,服务器经过正则进行匹配处理,最终生成HTML和数据返回给前端
  • 以上就是后端路由,简单来讲路由就是用来跟后端服务器进行交互的一种方式
  • 可是这种方式很糟糕的状况就是整个页面都由后端人员来维护,若是前端人员须要开发页面就要经过修改JSP等页面进行修改,这种状况下HTML页面代码和逻辑会混合在一块儿,不管是编写仍是维护都很糟糕和麻烦
  • 因而就出现了先后端分离的阶段

先后端分离🚀

  • 随着Ajax的出现,有了先后端分离的开发模式
  • 当咱们请求数据接口的时候,后端只提供API来返回数据,前端经过Ajax来获取数据并渲染到页面中
  • 这样能够很清晰的分配先后端的职责,让前端专心于用户的交互和可视化,让后端专心于数据的处理

SPA(单页Web应用)阶段🍻

  • 在传统的网页中,每一个HTML文件都是一个完成的HTML页面,每当访问一个URL就要去服务端请求大量的数据,不仅仅增长了性能损耗还破换了用户浏览体验
  • SPA(单页Web应用)中,单纯的浏览器地址改变, 利用了JavaScript动态变换网页内容,网页不会重载
  • 简单来讲就是在单页面Web网页中, 页面的切换就是视图之间的切换
  • 其实SPA最主要的特色就是在先后端分离基础上加了一层前端路由

前端路由的核心

  • 改变URL,可是页面不进行总体的刷新
  • 而网站与用户交互时不进行总体刷新的同时,能够有局部的内容进行改变
  • 前端渲染把渲染的任务交给了浏览器,经过客户端来解决页面的构建,这个很大程度上缓解了服务端的压力。并且配合前端路由,无缝的页面切换体验天然是对用户友好的。

说了这么多,那该如何实现呢?接下来讲到的hash(哈希)模式和history模式就是前端路由的实现方式react

hash模式

  • hashURLhash(#)及后面的那部分,经常使用做锚点在页面内进行导航,改变URL中的hash部分不会引发页面刷新
  • 浏览器不会对#号后面的路径对服务端发起路由请求,也就是说当你请求一个https://juejin.cn/#123https://juejin.cn/其实到服务端都是去请求https://juejin.cn/这个页面的内容
  • hash的改变会经过触发hashchange事件监听URL的变化,来渲染对应的页面,经过浏览器前进后退改变URL、经过标签改变URL、经过window.location改变URL,这几种状况改变URL都会触发hashchange事件

经常使用的APIvue-router

window.location.hash = '123' // 设置 url 的hash,会在当前url后加上 '#123'
let hash = window.location.hash  
console.log(hash) //#123
window.addEventListener('hashchange', function(){ 
    // 监听hash变化
})
复制代码

image.png

history模式

  • window.history属性指向history对象,它表示当前窗口的浏览历史
  • history对象保存了当前窗口访问过的全部页面网址,经过window.history.length能够得出当前窗口一共访问过几个网址,经过window.history.state能够获得History堆栈最上层的状态值
window.history.length //4
window.history.state //null
复制代码

image.png

history模式中,URL不带#号,那他看起来就和一般的URL同样了,那该如何改变URL不引发页面刷新呢?后端

那么就须要用到在HTML5的规范中,history对象新增了的pushStatereplaceState两个方法, 这两个方法都接受三个参数(state, title, url)跨域

  • state:须要保存的数据对象,经过pushState方法能够将该对象内容传递到新页面中
  • title:指标题,但通常用不到,没有浏览器能够支持填null便可
  • url:设定新的历史记录的url,必须与当前页面处在同一个域,不指定的话则为当前的路径,若是设置了一个跨域网址,则会报错,这样设计的目的是,防止恶意代码让用户觉得他们是在另外一个网站上,由于这个方法不会致使页面跳转,url能够是绝对路径,也能够是相对路径

history.pushState()

  • 该方法能够理解为在历史记录添加一条记录
let state={
    app:'sth'
}
window.history.pushState(state, '', '') 
console.log(window.history.state) //{app:"sth"}
console.log(window.history.length)//每执行一次pushState则会改变
复制代码
  • url设置了跨域网址则会报错

image.png

history.replaceState()

  • history.replaceState() 的使用与 history.pushState() 很是类似,区别在于 replaceState() 是修改了当前的历史记录项而不是新建一个。
let state={
    app:'sth'
}
window.history.replaceState(state, '', '') 
console.log(window.history.state) //{app:"sth"}
console.log(window.history.length)//每执行replaceState不会改变
复制代码

因为history.pushState()history.replaceState()能够改变url同时,不会刷新页面,因此在HTML5中的histroy也具有了实现前端路由的能力浏览器

两种模式的比较👈

hash history
外观 有些许丑 比较优雅
兼容性 兼容性较好,能够兼容IE8 兼容性相对较差
锚点功能 由于是在url加#致使锚点失效 有效
设置URL 由于只可修改#后面的hash因此只可设置与当前同文档的 URL 设置的新 URL 能够是与当前 URL 同源的任意 URL
刷新限制 无需服务端配合 须要服务端配合

写在最后👋

  • 前端路由的核心实现原理理解起来其实很简单,可是结合具体框架后(vue-router,react-router),框架增长了不少特性,如动态路由、路由参数、路由动画等等,这些致使路由实现变的复杂
  • 可是只要真正理解了其中遇到问题也就迎刃而解了,在写这篇文章的时候也让我从新巩固梳理了基础,因此只要把学到的东西善于总结起来就会不断扩充本身的大脑
  • 若是您以为这篇文章有帮助到您的的话不妨点赞支持一下哟~~😛

参考

hash模式和history模式服务器

前端路由是什么东西?markdown

相关文章
相关标签/搜索