前端路由

前置知识

hash 路由

原理
修改 location.hash 值(页面不会刷新),如果修改前后值不一致,则往 history 中增加一条记录;当 hash 值改变时会触发 hashchange 事件,此时便可以进行一些 dom 操作。
代码

class HashRouter {
  constructor(options) {
    // 保存路由信息
    this.routes = options.routes;
    // 监听 hash 值
    window.addEventListener('hashchange', this.render.bind(this));
    // 页面加载完成
    window.addEventListener('load', this.load.bind(this));
  }

  load() {
    // 使用 vue-router 中的标签
    this.view = document.querySelector('router-view');
    this.links = document.querySelectorAll('router-link');
    this.links.forEach(item => item.addEventListener('click', () => this.push(item.getAttribute('to'))));
  }

  // 路由
  push(path) {
    location.hash = path;
  }

  // 获取当前路径
  getPath() {
    return location.hash.replace(/^#/, '') || '/';
  }

  // 获取当前路由
  getRoute() {
    const path = this.getPath();
    return this.routes.find(route => route.path === path);
  }

  // 渲染
  render() {
    const route = this.getRoute();
    this.view.innerHTML = route?.component;
  }
}

history 路由

原理
使用 history.pushStatehistory.replaceStatehistory 中添加一条记录(不会刷新页面),可以进行一些 dom 操作;当使用前进和后退功能时(添加时不刷新页面,前进与后退也不会刷新页面),会触发 popState 事件,此时可以进行一些 dom 操作。
代码

class HistoryRouter {
  constructor(options) {
    this.routes = options.routes;
    window.addEventListener('popstate', this.render.bind(this));
    window.addEventListener('load', this.load.bind(this));
  }

  load() {
    this.view = document.querySelector('router-view');
    this.links = document.querySelectorAll('router-link');
    this.links.forEach(item => item.addEventListener('click', () => this.push(item.getAttribute('to'))));
    this.render();
  }

  push(path) {
    history.pushState(null, null, path);
    this.render();
  }

  getPath() {
    return location.pathname;
  }

  getRoute() {
    const path = this.getPath();
    return this.routes.find(route => route.path === path);
  }

  render() {
    const route = this.getRoute();
    this.view.innerHTML = route?.component;
  }
}

以上只是给出大体思路,实际还有许多问题要处理。

posted @ 2022-03-13 19:46  梦渊同学  阅读(47)  评论(0)    收藏  举报