# 路由器参考手册

下面的部分重点介绍了一些路由器的核心概念。

# 路由器导入

Angular 的 Router 是一个可选服务,它为指定的 URL 提供特定的组件视图。它不是 Angular 核心的一部分,因此它位于自己的包 @angular/router 中。

从任何其它的 Angular 包中导入你需要的东西。

src/app/app.module.ts (import)

import { RouterModule, Routes } from '@angular/router';

关于浏览器 URL 风格的更多信息,请参阅 LocationStrategy 和浏览器 URL 风格 。

# 配置

带路由的 Angular 应用中有一个 Router服务的单例实例。当浏览器的 URL 发生变化时,该路由器会查找相应的 Route,以便根据它确定要显示的组件。

在配置之前,路由器没有任何路由。下面的例子创建了五个路由定义,通过 RouterModule.forRoot()方法配置路由器,并把结果添加到 AppModuleimports数组中。

src/app/app.module.ts (excerpt)

const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  { path: 'hero/:id',      component: HeroDetailComponent },
  {
    path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
    // other imports here
  ],
  ...
})
export class AppModule { }

appRoutes路由数组描述了如何导航。把它传给模块的 imports数组中的 RouterModule.forRoot()方法来配置路由器。

每个 Route都会把一个 URL path映射到一个组件。路径中没有前导斜杠。路由器会为你解析并构建最终的 URL,这样你就可以在应用视图中导航时使用相对路径和绝对路径了。

第二个路由中的 :id是路由参数的标记。在像 /hero/42这样的 URL 中,“42”是 id参数的值。相应的 HeroDetailComponent用这个值来查找并显示 id为 42 的英雄。

第三个路由中的 data属性是存放与该特定路由关联的任意数据的地方。每个激活的路由都可以访问 data属性。可以用它来存储页面标题,面包屑文本和其它只读静态数据等项目。可以用解析器守卫来检索动态数据。

第四个路由中的空路径表示该应用的默认路径 - 当 URL 中的路径为空时通常要去的地方,就像它在刚进来时一样。这个默认路由重定向到了 /heroes这个 URL 的路由,因此会显示 HeroesListComponent

如果你需要查看导航生命周期中发生了什么事件,可以把 enableTracing选项作为路由器默认配置的一部分。这会把每个导航生命周期中发生的每个路由器事件都输出到浏览器控制台中。enableTracing只会用于调试目的。你可以把 enableTracing: true选项作为第二个参数传给 RouterModule.forRoot()方法。

# 路由出口

RouterOutlet是一个来自路由器库的指令,虽然它的用法像组件一样。它充当占位符,用于在模板中标记出路由器应该显示把该组件显示在那个出口的位置。

<router-outlet></router-outlet>
<!-- Routed components go here -->

对于上面的配置,当这个应用的浏览器 URL 变为 /heroes时,路由器就会把这个 URL 与路由路径 /heroes匹配,并把 HeroListComponent作为兄弟元素显示在宿主组件模板中的 RouterOutlet下方。

# 路由链接

要想通过某些用户操作(比如单击一下 a 标签)进行导航,请使用 RouterLink

考虑下面的模板:

src/app/app.component.html

<h1>Angular Router</h1>
<nav>
  <a routerLink="/crisis-center" routerLinkActive="active" ariaCurrentWhenActive="page">Crisis Center</a>
  <a routerLink="/heroes" routerLinkActive="active" ariaCurrentWhenActive="page">Heroes</a>
</nav>
<router-outlet></router-outlet>

a 标签上的 RouterLink指令让路由器可以控制这些元素。导航路径是固定的,所以你可以给 routerLink赋值一个字符串(“一次性”绑定)。

如果导航路径更加动态,你可以给它绑定到一个模板表达式,该表达式要返回一个链接参数数组。路由器会把该数组解析成一个完整的 URL。

# 活动路由链路

RouterLinkActive指令会根据当前的 RouterState切换活动 RouterLink上所绑定的 CSS 类。

在每个 a 标签上,你会看到一个到 RouterLinkActive指令的属性绑定,就像

routerLinkActive="..."

等号 =右侧的模板表达式,包含一个以空格分隔的 CSS 类字符串,当这个链接处于活动状态时,路由器就会加上这些字符串,并在非活动状态时删除。你可以把 RouterLinkActive指令设置成一串类的字符串,比如 routerLinkActive="active fluffy",也可以把它绑定到一个返回这样一个字符串的组件属性上,比如

[routerLinkActive]="someStringProperty"

活动路由链接会级联到路由树的每个级别,这样父路由和子路由链接就可以同时处于活动状态。要覆盖这种行为,可以用 { exact: true }表达式绑定到 [routerLinkActiveOptions]输入绑定。使用 { exact: true }之后,给定的 RouterLink只有在 URL 与当前 URL 完全匹配时才会激活。

RouterLinkActive还允许你轻松地将 aria-current属性应用于活跃元素,从而为所有用户提供更易于访问的体验。有关更多信息,请参阅无障碍性最佳实践活动链接标识部分。

# 路由器状态

每个成功的导航生命周期结束后,路由器都会构建一个 ActivatedRoute对象树,它构成了路由器的当前状态。你可以从任何地方使用应用的 Router服务和 routerState属性来访问当前的 RouterState

RouterState中的每个 ActivatedRoute都提供了向上或向下遍历路由树的方法,用于从父路由、子路由和兄弟路由中获取信息。

# 激活路由

路由的路径和参数可以通过注入名为 ActivatedRoute 的路由服务获得。它提供了大量有用的信息,包括:

| 属性 | Property | 详情 | Details | | :--- | :--- | :--- | :--- | | url| 一个路由路径的 Observable,是一个由路由路径的各个部分组成的字符串数组。An Observable of the route paths, represented as an array of strings for each part of the route path. | | data| 包含提供给当前路由的 data 对象的 Observable。也包含任何由解析守卫解析出的值。An Observable that contains the data object provided for the route. Also contains any resolved values from the resolve guard. | | params| Observable 可以包含此路由的必选和可选参数。An Observable that contains the required and optional parameters specific to the route. | | paramMap| 一个包含该路由的必要参数和可选参数 map 的 Observable。这个 map 支持从同一个参数中获得单个或多个值。An Observable that contains a map of the required and optional parameters specific to the route. The map supports retrieving single and multiple values from the same parameter. | | queryParamMap| 一个包含适用于所有路由的查询参数 map 的 Observable。这个 map 支持从同一个查询参数中获得单个或多个值。An Observable that contains a map of the query parameters available to all routes. The map supports retrieving single and multiple values from the query parameter. | | queryParams| Observable 可以包含对所有路由都可用的查询参数。An Observable that contains the query parameters available to all routes. | | fragment| 一个适用于所有路由的 URL 片段的 Observable。An Observable of the URL fragment available to all routes. | | outlet| 用来渲染该路由的 RouterOutlet 的名字。对于无名出口,这个出口的名字是 primary。The name of the RouterOutlet used to render the route. For an unnamed outlet, the outlet name is primary. | | routeConfig| 包含原始路径的那个路由的配置信息。The route configuration used for the route that contains the origin path. | | parent| 当该路由是子路由时,表示该路由的父级 ActivatedRoute。The route's parent ActivatedRoute when this route is a child route. | | firstChild| 包含该路由的子路由列表中的第一个 ActivatedRoute。Contains the first ActivatedRoute in the list of this route's child routes. | | children| 包含当前路由下所有激活的子路由。Contains all the child routes activated under the current route. |

# 路由器事件

Router在每次导航过程中都会通过 Router.events属性发出导航事件。这些事件如下表所示。

| 路由事件 | Router event | 详情 | Details | | :--- | :--- | :--- | :--- | | NavigationStart| 开始导航时触发。Triggered when navigation starts. | | RouteConfigLoadStart| 路由器惰性加载某个路由配置之前触发。Triggered before the Router lazy loads a route configuration. | | RouteConfigLoadEnd| 某个路由惰性加载完毕后触发。Triggered after a route has been lazy loaded. | | RoutesRecognized| 路由器解析完 URL,并且识别出路由时触发。Triggered when the Router parses the URL and the routes are recognized. | | GuardsCheckStart| 路由器开始执行路由守卫时触发。Triggered when the Router begins the Guards phase of routing. | | ChildActivationStart| 路由器开始激活某个路由的子路由时触发。Triggered when the Router begins activating a route's children. | | ActivationStart| 路由器开始激活某个路由时触发。Triggered when the Router begins activating a route. | | GuardsCheckEnd| 路由器完全完成了路由守卫阶段时触发。Triggered when the Router finishes the Guards phase of routing successfully. | | ResolveStart| 路由器开始路由解析(Resolve)阶段时触发。Triggered when the Router begins the Resolve phase of routing. | | ResolveEnd| 路由器成功完成了路由解析(Resolve)阶段时触发。Triggered when the Router finishes the Resolve phase of routing successfully. | | ChildActivationEnd| 路由器激活完某个路由的子路由时触发。Triggered when the Router finishes activating a route's children. | | ActivationEnd| 路由器正在激活某个路由时触发。Triggered when the Router finishes activating a route. | | NavigationEnd| 导航成功结束时触发。Triggered when navigation ends successfully. | | NavigationCancel| 导航被取消时触发。这可能是因为在导航期间某个路由守卫返回了 false 或通过返回 UrlTree 而进行了重定向。Triggered when navigation is canceled. This can happen when a Route Guard returns false during navigation, or redirects by returning a UrlTree. | | NavigationError| 当导航因为非预期的错误而失败时触发。Triggered when navigation fails due to an unexpected error. | | Scroll| 表示一个滚动事件。Represents a scrolling event. |

当启用了 enableTracing选项时,Angular 会把这些事件都记录到控制台。关于筛选路由器导航事件的范例,请参阅 Angular 中的 Observables 一章的路由器部分。

# 路由器术语

这里是一些关键的 Router术语及其含义:

| 路由器部件  | 详情  | | :--- | :--- | :--- | :--- | | Router| 为活动 URL 显示应用中的组件。管理从一个组件到另一个的导航。| | RouterModule| 一个单独的 NgModule,它提供了一些必要的服务提供者和一些用于在应用视图间导航的指令。 | | Routes| 定义一个路由数组,每一个条目都会把一个 URL 路径映射到组件。| | Route| 定义路由器如何基于一个 URL 模式导航到某个组件。大部分路由都由一个路径和一个组件类组成。 | | RouterOutlet| 该指令 (&lt;router-outlet&gt;) 用于指出路由器应该把视图显示在哪里。The directive (&lt;router-outlet&gt;) that marks where the router displays a view. | | RouterLink| 用于将可点击的 HTML 元素绑定到某个路由的指令。单击带有 routerLink 指令且绑定到字符串或链接参数数组的元素,将触发导航。 | | RouterLinkActive| 当包含在元素上或内部的关联 routerLink 变为活动/非活动状态时,用于从 HTML 元素添加/删除类的指令。它还可以设置活动链接的 aria-current 以获得更好的无障碍性。| | ActivatedRoute| 一个提供给每个路由组件的服务,其中包含当前路由专属的信息,比如路由参数、静态数据、解析数据、全局查询参数和全局片段。 | | RouterState| 路由器的当前状态,包括一棵当前激活路由的树以及遍历这棵路由树的便捷方法。 | | 链接参数数组Link parameters array| 一个由路由器将其解释为路由指南的数组。你可以将该数组绑定到 RouterLink 或将该数组作为参数传给 Router.navigate 方法。 | | 路由组件Routing component| 一个带有 RouterOutlet 的 Angular 组件,可基于路由器的导航来显示视图。|

Last Updated: 5/13/2023, 10:57:08 AM