你必须知道的路由原理

hash路由

利用hash实现路由切换

<html lang="en">
<head>
  <style>
    #root{
      height: 200px;
      border: 1px solid red;
    }
  style>
head>
<body>
  <a href="#/a">跳转到/aa>
  <a href="#/b">跳转到/ba>
  <div id="root">div>
  <script>
    let container = document.getElementById('root');
    window.addEventListener('hashchange',function (e) {
      console.log(e);
      container.innerHTML = `当前的路径是${window.location.hash.slice(1)}`;
    })
  script>
body>
html>
复制代码

  • 当通过hash切换路由的时候回触发hashchange事件
  • 通过window.location.hash可以拿到当前页面的hash

Browser路由

利用H5——API实现路由切换

history对象

提供了操作浏览器会话历史的接口

  • 【1】back跳到上一个路径,作用同浏览器的回退按钮
  • 【2】forward跳到下一个路径,作用同浏览器的前进按钮
  • 【3】go跳到某个路径
    • 【3-1】参数相对于当前路径的队列数字,例如go(1) === forword() ,go(-1) === back();
  • 【4】length表示当前路径队列中存储的路径个数
  • 【5】pushState在当前路径队列中增加新的路径,并且跳转到新路径;length + 1
    • 【5-1】参数三个history.pushState({name:'新的状态'},'新的标题(已经废弃)','/新的路径')
  • 【6】replaceState在当前的路径队列中用新的替换当前路径;length不变
    • 【6-2】参数同pushState

原理

<html lang="en">
<head>
  <style>
    #root {
      height: 200px;
      border: 1px solid red;
    }
  style>
head>
<body>
  <button onclick="push('/a')">/abutton>
  <button onclick="push('/b')">/bbutton>
  <button onclick="push('/c')">/cbutton>
  <div id="root">div>
  <script>
    let container = document.getElementById('root');
    /**
     * 监听弹出状态的事件(出栈操作)
     */
    window.onpopstate = function (e) {
      console.log(e);
      container.innerHTML = e.state.to;
    }
    function push(to) {
      /**
       * pushState (入栈操作)
       * 三个参数 1.新的状态对象 2.标题(已经废弃) 3.跳转到的路径
       */
      window.history.pushState({ to }, null, to);
    }
  script>
body>
html>
复制代码

  • 由上图可以看出当点击路由按钮的时候实现了路径的切换
  • 点击浏览器的回退或者前进的时候实现了路径的切换和视图的切换(即触发了window.onpopstate)
  • 但是我们想要的效果应该是点击路由切换按钮的时候也进行视图的切换,文章前的你肯定跟我有一样的想法——绑定window.onpushstate事件,但是很遗憾,浏览器并没有给我们提供这个事件。

优化pushState && 实现onpushstate方法——实现点击路由切换按钮同时进行视图切换

let oldPushState = window.history.pushState; // 保存原有的pushState方法;
window.history.pushState = function(state,title,url){
    onpushstate(state,title,url); // 调用我们手写的onpushstate切换视图
    oldPushState.call(window.history,state,title,url); // 调用原有的pushState方法实现路由切换
}
window.onpushstate = function(state,title,url){
    container.innerHTML = state.to || url;
}
复制代码

写在最后

文章主要是从底层的角度剖析了单页面应用路由的实现原理,三大框架的路由原理也是基于这个底层思想实现,后续会为大家带来React-Router的源码解析;如果觉得写的还可以帮忙点个?,?小生将不胜感激?。

转载于:https://juejin.im/post/5cf27d9d6fb9a07ed440e924

你可能感兴趣的:(你必须知道的路由原理)