2020了你还不懂前端路由原理吗

287 阅读2分钟

一、路由是什么?为什么要使用路由

1.1 在传统的网页中,我们都是使用网页跳转,这样子会导致页面会重新渲染,去加载那些加载过的东西,这样子网页访问速度变慢,性能也会降低

1.2 路由就是通过监听url的变化去动态渲染我们所需要的东西,这样子就不用重复加载那些已经加载过的

二、路由的原理及如何实现路由

2.1 路由的原理就是通过监听url的变化

2.2 实现路由的方式有两种,一种是通过hash,一种是通过H5中的history

三、实现路由的方式 --- hash

3.1 我们可以通过hashchange事件来监听当url的hash值变化时做处理

3.2 我们可以举一个具体场景,我们写三个网页,分别是 1,2,3,页面的内容也分别是1,2,3,按照我们平时的界面我们会写三个界面具体是网页1,网页2,网页3,当我们也可以不用写三个网页,只要通过监听url的变化去改变页面的值就可以了

<body>
  <ul>
      <li><a href="#/">turn one</a></li>
      <li><a href="#/two">turn two</a></li>
      <li><a href="#/three">turn three</a></li>
  </ul>
</body>

//js部分
class Routers {
  constructor() {
    this.routes = {};
    this.currentUrl = '';
    this.refresh = this.refresh.bind(this);
    window.addEventListener('load', this.refresh, false);
    window.addEventListener('hashchange', this.refresh, false);
  }

  route(path, callback) {
    this.routes[path] = callback || function() {};
  }

  refresh() {
    this.currentUrl = location.hash.slice(1) || '/';
    this.routes[this.currentUrl]();
  }
}

window.Router = new Routers();
var content = document.querySelector('body');
// change Page anything
function changeText(text) {
  content.innerHtml= text;
}
Router.route('/', function() {
  changeText('yellow');
});
Router.route('/two', function() {
  changeText('two');
});
Router.route('/three', function() {
  changeText('three');
});

但这里我们并没有实现前进后退的功能,实现起来比较繁琐,而且功能会有bug,我们这里就不去一一实现了

四、实现路由的方式 --- H5的history

4.1 当活动的历史记录项发生变化时,popstate事件都会被传递给window对象。如果当前活动的历史记录项是被pushState创建的,或者是由replaceState改变的,那么popstate事件的状态属性state会包含一个当前历史记录状态对象的拷贝

<body>
  <ul>
      <li><a href="#/">turn one</a></li>
      <li><a href="#/two">turn two</a></li>
      <li><a href="#/three">turn three</a></li>
  </ul>
</body>

//js部分
class Routers {
  constructor() {
    this.routes = {};
    this.refresh = this.refresh.bind(this);
    window.addEventListener('load', this.refresh, false);
    window.addEventListener('popState', function (e) {
      this.refresh(e.state.path), false
    });
  }

  route(path, callback) {
    history.pushState({path: path}, null, path);
    this.routes[path] = callback || function () {};
  }

  refresh(path) {
    this.routes[path]();
  }
}

window.Router = new Routers();
const content = document.querySelector('body');
const ul = document.querySelector('ul');

// change Page anything
function changeText(text) {
  content.innerHtml = text;
}

Router.route('/', function () {
  changeText('yellow');
});
Router.route('/two', function () {
  changeText('two');
});
Router.route('/three', function () {
  changeText('three');
});

ul.addEventListener('click', e => {
  if (e.target.tagName === 'A') {
    e.preventDefault();
    Router.go(e.target.getAttribute('href'));
  }
});