前端路由

前置知识

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 @   梦渊同学  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示