如何通过100行代码实现一个迷你router?

Posted 修仙大橙子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过100行代码实现一个迷你router?相关的知识,希望对你有一定的参考价值。

知识储备

如何操作浏览器地址?

我们可以使用下面三种方法,来修改浏览器的地址

  • location.assign(url)
  • window.location = url
  • location.href = url(常见)

修改以下location对象的属性值,会导致当前页面重新加载

// 假如当前url为:https://www.example.com/

// 把url修改为:https://www.example.com/?t=example
location.search = \'?t=example\';

// 把url修改为:https://example.com/?t=example
location.hostname = \'example.com\';

// 把url修改为:https://www.example.com/example
location.pathname = \'example\';

// 把url修改为:https://www.example.com:8080
location.port = 8080

修改hash时,浏览器历史中会新增加一条记录,但是并不会刷新页面。因此SPA应用中,hash也是一种切换路由的方式。

// 假如当前url为:https://www.example.com/

// 把url修改为:https://www.example.com/#example
location.hash = \'#example\';

使用location.replace(url)方法跳转的url,并不会增加历史记录。

使用location.reload()方法可以重新加载当前页面,是否传参的区别如下:

location.reload(); // 重新加载,可能是从缓存加载
location.reload(true); // 重新加载,从服务器加载

如何导航页面?

使用go(n)可以在用户记录中沿任何方向导航(即可以前进也可以后退)。正值表示在历史中前进,负值表示在历史中后退。

假如要前进1页,那么可以使用window.history.`go(1)。同时,也可以使用window.history.forward()`来做相同的事情。
假如要后退1页,那么可以使用window.history.`go(-1)。同时,也可以使用window.history.back()`来做相同的事情。

如果使用window.history.go(0)window.history.go()都会重新加载当前页面。

如何改变页面的地址,但是不会重新加载页面并且怎样监听这些改变?

使用hash

上面我们说到了,修改hash可以做到改变页面的地址,在浏览器历史中添加一条记录,但是不会重新加载页面。

我们同时可以配合hashchange事件,监听页面地址hash的变化。

使用history.pushState()、history.replaceState()

使用history.pushState(),类似是执行了location.href = url,但是并不会重新加载页面。假如用户执行了后退操作,将会触发popstate事件。

使用history.replaceState(),类似是执行了location.replace(url),但是并不会重新加载页面。

注意,执行pushState、replaceState方法后,虽然浏览器地址有改变,但是并不会触发popState事件

实现一个mini-router

开始编写构造函数

首先我们需要确定的是,我们的路由应该需要下面4个属性:

  • routes:一个数组,包含所有注册的路由对象
  • mode: 路由的模式,可以选择hashhistory
  • base:根路径
  • constructor:初始化新的路由实例
class MiniRouter {
  constructor(options) {
    const { mode, routes, base } = options;
    
    this.mode = mode || (window.history.pushState ? \'history\' : \'hash\');
    this.routes = routes || [];
    this.base = base || \'/\';
  }
}

export default MiniRouter;

增加添加路由对象方法

路由对象中包含下面两个属性

  • path:由正则表达式代表的路径地址(并不是字符串,后面会详细解释)
  • cb:路由跳转后执行的回调函数
class MiniRouter {
  constructor(options) {
    const { mode, routes, base } = options;
    
    this.mode = mode || (window.history.pushState ? \'history\' : \'hash\');
    this.routes = routes || [];
    this.base = base || \'/\';
  }
  
  // 添加路由对象 

以上是关于如何通过100行代码实现一个迷你router?的主要内容,如果未能解决你的问题,请参考以下文章

想安装一个迷你linux,只要有基本的命令行操作就可以,不需要图形介面,请问如何实现?

从0开始:500行代码实现 LSM 数据库

100行Python代码实现贪吃蛇小游戏

值得学习练手的 5 个 Python 迷你程序(附代码)

mysql命令行批量插入100条数据命令

TensorFlow2 100 行代码实现 VGG13