导航
导航
文章目录
  1. 路由
  2. History
  • hash
  • 前端路由优缺点
  • 前端路由的实现原理

    路由

    在现代前端开发中,路由是非常重要的一环。但路由到底是什么呢?有些说:路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同。这是从路由的用途上来解释路由是什么的,还有一种说法是:路由就是URL到函数的映射。这是从路由的实现原理上来解释路由是什么的。这两种说法都很有道理。

    早期的路由都是后端实现的,直接根据 url 来 reload 页面,页面变得越来越复杂服务器端压力变大,随着 ajax 的出现,页面实现非 reload 就能刷新数据,也给前端路由的出现奠定了基础。我们可以通过记录 url 来记录 ajax 的变化,从而实现前端路由。

    前端路由说白了就是监听浏览器路由地址的变化,渲染不同的页面或组件。
    下面主要讲两种主流方式实现前端路由:

    History

    这里不细说每一个 API 的用法,大家可以看 MDN 的文档:https://developer.mozilla.org…

    14年后,因为HTML5标准发布,新增了两个 API,history.pushState 和 history.replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。

    这两个 API 都接收三个参数,分别是

    • 状态对象(state object) — 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
    • 标题(title) — FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。
    • 地址(URL) — 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。
      相同之处是两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。

    不同之处在于,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。

    我们拿大百度的控制台举例子(具体说是我的浏览器在百度首页打开控制台。。。)

    我们在控制台输入

    1
    window.history.pushState(null, null, "https://www.baidu.com/?name=hzzly");

    好,我们观察此时的 url 变成了这样
    https://www.baidu.com/?name=hzzly

    我们这里不一一测试,直接给出其它用法,大家自行尝试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    window.history.pushState(null, null, "https://www.baidu.com/name/hzzly");
    //url: https://www.baidu.com/name/hzzly

    window.history.pushState(null, null, "?name=hzzly");
    //url: https://www.baidu.com?name=hzzly

    window.history.pushState(null, null, "name=hzzly");
    //url: https://www.baidu.com/name=hzzly

    window.history.pushState(null, null, "/name/hzzly");
    //url: https://www.baidu.com/name/hzzly

    window.history.pushState(null, null, "name/hzzly");
    //url: https://www.baidu.com/name/hzzly

    每次改变 url 页面并没有刷新,同样根据上文所述,浏览器会产生历史记录。

    我们需要一个根据监听history变化触发的事件 —— popstate 事件

    1
    2
    3
    4
    5
    function matchAndUpdate () {
    // 匹配路径 做 dom 更新操作
    }

    window.addEventListener('popstate', matchAndUpdate)

    hash

    我们经常在 url 中看到 #,这个 # 有两种情况,一个是我们所谓的锚点,比如典型的各个标题之间的跳转等,路由里的 # 不叫锚点,我们称之为 hash。

    同样我们需要一个根据监听哈希变化触发的事件 —— hashchange 事件

    1
    2
    3
    4
    5
    function matchAndUpdate () {
    // 匹配 hash 做 dom 更新操作
    }

    window.addEventListener('hashchange', matchAndUpdate)

    我们用 window.location 处理哈希的改变时不会重新渲染页面,而是当作新页面加到历史记录中,这样我们跳转页面就可以在 hashchange 事件中注册 ajax 从而改变页面内容。

    前端路由优缺点

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

    缺点:
    使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。