Skip to content
Mithril.js 2
Main Navigation 指南API

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

主题

Sidebar Navigation

入门

安装

简单应用

资源

JSX

在旧版浏览器上使用 ES6+

动画

测试

示例

第三方库集成

路径处理

关键概念

虚拟 DOM

组件

生命周期方法

键(Key)

自动重绘系统

杂项

框架对比

从 v1.x 迁移

从 v0.2.x 迁移

API

页面导航

路径处理 ​

m.route 和 m.request 都涉及路径的概念,用于生成路由跳转或请求的 URL。

路径类型 ​

路径主要有两种类型:原始路径和参数化路径。

  • 原始路径:直接作为 URL 使用的简单字符串。不会进行任何替换或分割,仅进行规范化处理,并将所有参数附加到末尾。
  • 参数化路径:支持在路径中插入值,默认情况下会对插入的值进行转义,既方便使用又能防止 URL 注入。

对于 m.request,路径几乎可以是任意 URL。但对于路由,路径只能是不包含协议(例如 https://)或域名的绝对 URL 路径名。

路径参数 ​

路径参数的使用方式很简单,有两种形式:

  • :foo - 将 params.foo 的值注入到 URL 中,并对该值进行转义。
  • :foo... - 将 params.foo 的值作为原始路径注入到 URL 中,不对其进行任何转义。

这里的 params 对象指的是 m.route.set(path, params) 或 m.request({url, params}) 中的 params。

当通过 m.route(root, defaultRoute, routes) 接收路由时,可以使用这些参数从路由中提取值。提取方式与路径生成基本相同,只是方向相反。

javascript
// 编辑单个条目
m.route(document.body, '/edit/1', {
  '/edit/:id': {
    view: function () {
    return [m(Menu), m('h1', '正在编辑用户 ' + m.route.param('id'))];
    },
  },
});

// 编辑由路径标识的条目
m.route(document.body, '/edit/pictures/image.jpg', {
  '/edit/:file...': {
    view: function () {
      return [m(Menu), m('h1', '正在编辑文件 ' + m.route.param('file'))];
    },
  },
});

在第一个例子中,如果导航到示例中的默认路由,m.route.param("id") 将读取为 "1"。在第二个例子中,m.route.param("file") 将读取为 pictures/image.jpg。

路径参数可以用 /、- 或 . 分隔,从而实现动态路径段,比单一的路径名更加灵活。例如,可以匹配 "/edit/:name.:ext" 这样的路由,以便根据文件扩展名进行编辑,或者匹配 /:lang-:region/view 这样的路由,以便进行本地化路由。

路径参数是贪婪匹配的。给定一个声明的路由 "/edit/:name.:ext",如果导航到 /edit/file.test.png,则提取的参数将是 {name: "file.test", ext: "png"}, 而不是 {name: "file", ext: "test.png"}。类似地,给定 "/route/:path.../view/:child...",如果访问 /route/foo/view/bar/view/baz,则提取的参数将是 {path: "foo/view/bar", child: "baz"}。

参数规范化 ​

插入到路径名中的路径参数会被省略,不会出现在查询字符串中。这样做既方便,又能保持路径名的可读性。例如,以下代码会发送一个服务器请求:GET /api/user/1/connections?sort=name-asc,省略了 URL 字符串中重复的 id=1 参数。

javascript
m.request({
  url: 'https://example.com/api/user/:userID/connections',
  params: {
    userID: 1,
    sort: 'name-asc',
  },
});

以下示例与上述示例等效:

javascript
m.request({
  url: 'https://example.com/api/user/:userID/connections?sort=name-asc',
  params: {
    userID: 1,
  },
});

当然,也可以混合使用路径参数和查询参数。以下代码会发送一个 GET /api/user/1/connections?sort=name-asc&first=10 请求。

javascript
m.request({
  url: 'https://example.com/api/user/:userID/connections?sort=name-asc',
  params: {
    userID: 1,
    first: 10,
  },
});

这一特性也适用于路由匹配:可以匹配带有显式查询字符串的路由。匹配的参数会被保留以便使用,因此仍然可以通过 vnode 参数或通过 m.route.param 访问它们。请注意,虽然这是可行的,但通常不推荐这样做,因为应该优先使用路径来定义页面。如果需要为特定文件类型生成略有不同的视图,但从逻辑上讲,它仍然是一个类似查询的参数,而不是一个完全独立的页面,那么这在某些情况下可能很有用。

javascript
// 注意:通常*不*建议使用 - 你应该优先使用路径进行路由
// 声明,而不是查询字符串。
m.route(document.body, '/edit/1', {
  '/edit?type=image': {
    view: function () {
      return [m(Menu), m('h1', '正在编辑照片')];
    },
  },
  '/edit': {
    view: function () {
      return [m(Menu), m('h1', '正在编辑 ' + m.route.param('type'))];
    },
  },
});

查询参数是隐式使用的,无需显式命名即可接受。可以基于现有值进行匹配,例如在 "/edit?type=image" 中,但不需要使用 "/edit?type=:type" 来接受该值。实际上,Mithril.js 会将 "/edit?type=:type" 视为尝试按字面意思匹配 m.route.param("type") === ":type",因此通常不应该这样做。简而言之,使用 m.route.param("key") 或路由组件属性来读取查询参数。

路径规范化 ​

解析后的路径总是返回规范化的结果:所有重复的参数和多余的斜杠都会被删除,并且总是以斜杠开头。这些细微的差异常常会造成阻碍,使路由和路径处理变得比预期复杂。Mithril.js 内部会对路由路径进行规范化处理,但不会直接暴露当前规范化路由。(可以通过 m.parsePathname(m.route.get()).path 计算它。)

匹配时处理重复参数,查询字符串中的参数优先于路径名中的参数,URL 末尾的参数优先于开头的参数。

路径转义 ​

有些字符如果想按字面意思使用,就需要转义。幸运的是,encodeURIComponent 会对这些字符(以及更多字符)进行编码。在替换参数和添加查询参数时,Mithril.js 会根据需要自动使用此方法进行编码。以下是 Mithril.js 解释的字符:

  • : = %3A
  • / = %2F (仅在路径中需要)
  • % = %25
  • ? = %3F (仅在路径中需要)
  • # = %23

当然,还有其他一些字符必须按照 URL 规范进行转义,例如空格。但正如已经提到的,encodeURIComponent 会自动处理这些字符,并且 Mithril.js 在替换参数时会隐式地使用它。因此,只有在显式指定参数时才需要注意转义,例如在 m.request("https://example.com/api/user/User%20Name/:field", {params: {field: ...}}) 中。

Pager
上一页第三方库集成
下一页虚拟 DOM

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors

https://mithril.js.org/paths.html

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors