关于path-to-regexp的那点事

1,003 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

前言

在之前的篇章中我们实现了一个mini版react路由,其中我们地址的匹配方式很粗暴,直接通过location.params去匹配相应的参数。

在vue或者react的路由库中,都引用到一个第三方库path-to-regexp,该库的作用就是将一个字符串正则去匹配相应的路由地址。

image.png

react-router库部分源码:

var pathToRegexp = _interopDefault(require('path-to-regexp'));

function compilePath$1(path, options) {
  var cacheKey = "" + options.end + options.strict + options.sensitive;
  var pathCache = cache$1[cacheKey] || (cache$1[cacheKey] = {});
  if (pathCache[path]) return pathCache[path];
  var keys = [];
  var regexp = pathToRegexp(path, keys, options);
  var result = {
    regexp: regexp,
    keys: keys
  };

  if (cacheCount$1 < cacheLimit$1) {
    pathCache[path] = result;
    cacheCount$1++;
  }

  return result;
}

概述

path-to-regexp简介

安装指令:

npm install path-to-regexp --save

使用:

const { pathToRegexp, match, parse, compile } = require("path-to-regexp");

// pathToRegexp(path, keys?, options?)
// match(path)
// parse(path)
// compile(path)

pathToRegexp参数说明

第一个参数:匹配规则(必填)

让我们看看该库的使用:

import {pathToRegexp} from "path-to-regexp"

const result = pathToRegexp("/api/blogId/:id")

console.log(result) //输出结果是/^api\/blogId(?:\/([^\/#\?]+?))[\/#\?]?$/i,这是一个对象

截屏2022-06-07 下午11.17.21.png

尝试匹配路径:

import {pathToRegexp} from "path-to-regexp"

const result = pathToRegexp("api/blogId/:id")

console.log(result.exec("api/blogId/123"))
console.log(result.exec("api/blogId/123/"))
console.log(result.exec("/blogId/123"))
console.log(result.exec("api/blogId/123/456"))

截屏2022-06-07 下午11.18.22.png

第二个参数:包含匹配路径关键字的数组(可选)

查看第二个参数的内容:

import {pathToRegexp} from "path-to-regexp"

const keys = [];

const result = pathToRegexp("api/blogId/:id",keys)

console.log(result,keys)

查看打印结果:

截屏2022-06-07 下午11.19.25.png

通过打印的结果,我们会发现数组选项表示匹配到的内容,其中数组对象里的name表示匹配到的对应的地址参数key。

第三个参数:配置对象(可选)

  • sensitive:是否区分大小写,默认false
  • strict:是否启用严格模式,默认为false,当为true时不能匹配最后的斜杆“/”(如blogID/123/)
  • end:是否匹配到字符串的末尾,默认为true,在router里是通过isExact改变
  • start:当为true时,regexp将从字符串的开头匹配,默认值为true
  • delimiter:段的默认分隔符,例如[^/#?],其命名模式为(默认值:'/#?')
  • endsWith :可选字符或字符列表,将其视为“结束”字符
  • encode:在插入RegExp之前对字符串进行编码的函数
  • prefixes :分析时自动考虑前缀的字符列表(默认值:./)

小结

本篇我们主要介绍path-to-regexp在框架里的作用以及其基本用法,该库实现了通过正则匹配等规则对匹配结果进行封装。我们可以通过熟悉其基本用法,后续对其进行基本的实现。