Angular Router logo

Angular Router

Angular 框架内置的企业级路由系统,提供完整的导航控制、路由守卫、懒加载、预加载策略和路由动画能力,是 Angular 应用唯一的路由方案。

路由Angular企业级路由守卫

Angular Router 是 Angular 框架内置的企业级路由系统,提供五层路由守卫、智能预加载策略、View Transitions API 集成和完整的 RxJS 导航事件流,随 Angular CLI 自动包含。

Angular Router

Angular 框架内置的企业级路由系统,提供完整的导航控制、路由守卫、懒加载、预加载策略和路由动画能力,是 Angular 应用唯一的路由方案。

技术简介说明

Angular Router(@angular/router)是 Angular 框架的核心内置库,由 Google Angular 团队开发和维护。与 React/Vue 生态中的独立路由库不同,Angular Router 与框架深度集成——它在 Angular CLI 创建项目时自动包含,无需额外安装。Router 提供了从基础路由配置到企业级路由管理的完整能力:组件路由、模块/组件懒加载、多层路由守卫、数据预取(Resolve)、预加载策略、路由切换动画、滚动恢复等。

Angular Router 的设计哲学围绕企业级复杂需求展开。它通过 Routes 配置树定义路由结构,支持 Eager Loading(立即加载)和 Lazy Loading(按需加载)两种模式;通过五种路由守卫(canActivate、canActivateChild、canDeactivate、canMatch、resolve)实现精细的访问控制和数据预取;通过 PreloadingStrategy 实现智能预加载优化用户体验。从 v15 引入 Standalone Components 和函数式守卫开始,Angular Router 的配置模式发生了根本性变化——从 NgModule 驱动转向 provideRouter() 函数式配置。

Angular v17 是框架"文艺复兴"版本,带来了 View Transitions API 原生支持、Signals 集成、@defer 延迟视图等重大改进。v19/v20 进一步引入异步重定向、Router.getCurrentNavigation()?.abort() 导航取消 API、currentNavigation Signal(v20.2)等现代化特性。v21/v22 则聚焦于稳定性和 Zoneless 兼容。Angular Router 始终保持每 6 个月一次大版本更新的节奏,是前端路由领域最成熟的企业级方案之一。

基本信息

快速上手

安装

# 使用 Angular CLI 创建项目(自动包含 Router)
ng new my-app --routing
 
# 为已有项目添加路由能力(通常已内置,无需额外操作)
ng add @angular/router
 
# Angular Router 是 Angular 的核心包,随 @angular/core 一起安装
# 不需要单独 npm install,只需在配置中引入 provideRouter

基础配置

现代 Standalone 方式(Angular v17+,推荐):

// app.routes.ts — 路由配置
import { Routes } from '@angular/router'
 
export const routes: Routes = [
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full',
  },
  {
    path: 'home',
    loadComponent: () =>
      import('./home/home.component').then(m => m.HomeComponent),
  },
  {
    path: 'about',
    loadComponent: () =>
      import('./about/about.component').then(m => m.AboutComponent),
  },
  {
    path: 'users/:id',
    loadComponent: () =>
      import('./user/user-detail.component').then(m => m.UserDetailComponent),
    resolve: { user: userResolver },
  },
  {
    path: '**',
    loadComponent: () =>
      import('./not-found/not-found.component').then(m => m.NotFoundComponent),
  },
]
// app.config.ts — 应用配置
import { ApplicationConfig } from '@angular/core'
import {
  provideRouter,
  withPreloading,
  withComponentInputBinding,
  withViewTransitions,
  PreloadAllModules,
} from '@angular/router'
import { routes } from './app.routes'
 
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(
      routes,
      withPreloading(PreloadAllModules),
      withComponentInputBinding(),
      withViewTransitions(),
    ),
  ],
}
// app.component.ts — 根组件
import { Component } from '@angular/core'
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router'
 
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, RouterLink, RouterLinkActive],
  template: `
    <nav>
      <a routerLink="/home" routerLinkActive="active">首页</a>
      <a routerLink="/about" routerLinkActive="active">关于</a>
    </nav>
    <router-outlet />
  `,
})
export class AppComponent {}

最小示例

// main.ts — 应用启动
import { bootstrapApplication } from '@angular/platform-browser'
import { provideRouter } from '@angular/router'
import { AppComponent } from './app.component'
import { routes } from './app.routes'
 
bootstrapApplication(AppComponent, {
  providers: [provideRouter(routes)],
})

核心概念与架构

路由配置对象(Routes)

Angular Router 使用 Routes 类型(Route[])定义路由配置树。每个 Route 对象可包含:

字段说明
pathURL 路径段(支持参数 :id、通配符 **
pathMatch匹配策略:'prefix'(默认)或 'full'(精确匹配)
component即时加载的组件(Eager Loading)
loadComponent动态导入函数,返回组件(Lazy Loading,v15+)
loadChildren动态导入函数,返回子路由数组(模块级懒加载)
children嵌套子路由配置
canActivate路由激活守卫
canActivateChild子路由激活守卫
canDeactivate路由离开守卫
canMatch路由匹配守卫(v14.2+,替代已废弃的 canLoad
resolve数据预取解析器
data静态路由数据
redirectTo重定向目标(v20 起支持异步函数)
title页面标题(配合 TitleStrategy
outlets命名Outlet路由

三种组件加载模式

// 1. Eager Loading — 应用启动时立即加载
{ path: 'home', component: HomeComponent }
 
// 2. Lazy Loading 组件 — 按需加载独立组件(v15+ Standalone)
{ path: 'about', loadComponent: () => import('./about.component').then(m => m.AboutComponent) }
 
// 3. Lazy Loading 子路由 — 按需加载整棵子路由树
{ path: 'admin', loadChildren: () => import('./admin.routes').then(m => m.ADMIN_ROUTES) }

懒加载函数运行在当前路由的注入上下文中,可以使用 inject() 访问服务实现动态加载决策:

{
  path: 'dashboard',
  loadComponent: () => {
    const flags = inject(FeatureFlags)
    return flags.isPremium
      ? import('./premium-dashboard.component')
      : import('./basic-dashboard.component')
  },
}

路由守卫(Guards)

Angular Router 提供五种路由守卫,从 v15 起推荐使用函数式守卫(*Fn 类型):

import { inject } from '@angular/core'
import { CanActivateFn, CanDeactivateFn, CanMatchFn, ResolveFn, Router } from '@angular/router'
 
// 1. canActivate — 控制是否可进入路由
export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService)
  const router = inject(Router)
  return authService.isAuthenticated()
    ? true
    : router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } })
}
 
// 2. canDeactivate — 控制是否可离开路由(如未保存表单)
export const unsavedGuard: CanDeactivateFn<FormGroup> = (component) => {
  return component.isDirty
    ? window.confirm('有未保存的更改,确定离开吗?')
    : true
}
 
// 3. canMatch — 控制路由是否参与匹配(替代废弃的 canLoad)
export const featureFlagGuard: CanMatchFn = (route, segments) => {
  const flags = inject(FeatureFlags)
  return flags.isEnabled(route.data?.['featureKey'] ?? '')
}
 
// 4. resolve — 路由激活前预取数据
export const userResolver: ResolveFn<User> = (route) => {
  const userService = inject(UserService)
  return userService.getUser(route.paramMap.get('id')!)
}
 
// 5. canActivateChild — 控制子路由激活
export const childAuthGuard: CanActivateChildFn = (route, state) => {
  return inject(AuthService).isAuthenticated()
}

路由事件流

Angular Router 通过 Router.events 暴露完整的 RxJS Observable 导航事件流:

import { inject } from '@angular/core'
import { Router, NavigationStart, NavigationEnd, NavigationError } from '@angular/router'
import { filter, pairwise } from 'rxjs'
 
const router = inject(Router)
 
// 监听导航结束事件
router.events.pipe(
  filter((e): e is NavigationEnd => e instanceof NavigationEnd),
).subscribe(event => {
  console.log('Navigation ended to:', event.urlAfterRedirects)
})
 
// 导航错误处理
router.events.pipe(
  filter((e): e is NavigationError => e instanceof NavigationError),
).subscribe(event => {
  console.error('Navigation error:', event.error)
})

事件类型包括:NavigationStartNavigationEndNavigationCancelNavigationErrorNavigationSkippedRoutesRecognizedGuardsCheckStartGuardsCheckEndResolveStartResolveEndActivationStartActivationEndRouteConfigLoadStartRouteConfigLoadEndScroll

预加载策略

策略说明适用场景
NoPreloading默认,不预加载任何懒加载模块带宽敏感的应用
PreloadAllModules初始加载完成后预加载所有懒加载模块内网/企业应用
QuicklinkStrategy仅预加载视口中可见链接对应的模块(ngx-quicklink)公网应用,平衡体验与带宽
自定义策略实现 PreloadingStrategy 接口,按条件预加载基于用户角色/行为的智能预加载
// 自定义预加载策略示例
import { PreloadingStrategy, Route } from '@angular/router'
import { Observable, of } from 'rxjs'
 
export class SelectivePreloadingStrategy extends PreloadingStrategy {
  preload(route: Route, load: () => Observable<unknown>): Observable<unknown> {
    // 仅预加载标记了 data: { preload: true } 的路由
    return route.data?.['preload'] ? load() : of(null)
  }
}
 
// 配置
provideRouter(routes, withPreloading(SelectivePreloadingStrategy))

v19/v20/v21/v22 路由重大变化

Angular v19(2024年11月)

  • SSR 路由渲染配置:支持按路由配置 SSR 渲染方式(服务端/客户端)
  • Signal-based Resource API:路由 Resolve 支持 Signal 资源,防止竞态条件
  • HMR 支持:样式热替换稳定,模板热替换实验性支持

Angular v20(2025年5月)

  • 导航取消 APIRouter.getCurrentNavigation()?.abort() 可编程取消正在进行的导航
  • 异步重定向redirectTo 支持返回 PromiseObservable
    {
      path: '**',
      redirectTo: () => {
        const authService = inject(AuthService)
        return authService.checkAuth().then(isAuth =>
          isAuth ? '/dashboard' : '/login'
        )
      },
    }
  • View Transitions APIwithViewTransitions() 启用浏览器原生路由切换动画
  • 子路由 Resolve 访问父级数据:子路由 Resolve 可读取父路由已解析的数据
  • 自定义元素作为 RouterLink Host:Web Component 可作为 RouterLink 宿主
  • ViewportScroller 平滑滚动scrollToPosition(&#123; behavior: 'smooth' &#125;)

Angular v20.2(2025年8月)

  • currentNavigation Signal:替代废弃的 Router.getCurrentNavigation() 方法,提供响应式导航状态:
    import { Router } from '@angular/router'
    import { toSignal } from '@angular/core/rxjs-interop'
     
    const router = inject(Router)
    // 新的 Signal API(推荐)
    const navigation = router.currentNavigation // Signal<Navigation | null>
  • Zoneless 兼容:Router 在 Zoneless 应用中完全稳定

Angular v21(2025年11月)

  • isActive() 独立函数:创建计算 Signal 追踪 URL 激活状态:
    import { isActive } from '@angular/router'
    const isHomeActive = isActive('/home', { exact: true })
  • 路由与 Signals 集成进一步深化

Angular v22(2026年6月)

  • 稳定性版本:多个路由相关 API 从 Developer Preview 转为 Stable
  • Signal Forms 与路由表单的深度集成
  • Angular Aria 改善路由可访问性

核心特性

  • 模块/组件懒加载:基于 ES 动态 import() 的按需加载,支持组件级(loadComponent)和路由树级(loadChildren)粒度
  • 五层路由守卫:canActivate、canActivateChild、canDeactivate、canMatch、resolve,全面控制路由访问和数据预取
  • 函数式守卫与解析器:v15+ 的 CanActivateFnResolveFn 等,配合 inject() 简化实现
  • 智能预加载策略:内置 PreloadAllModulesNoPreloading,支持自定义 PreloadingStrategy 和第三方 QuicklinkStrategy
  • View Transitions API 集成:v17+ 通过 withViewTransitions() 启用浏览器原生路由切换动画
  • 路由组件输入绑定withComponentInputBinding() 自动将路由参数/数据绑定到组件 @Input() 或 Signal input()
  • 完整路由事件流:RxJS Observable 事件流覆盖导航全生命周期,支持细粒度拦截
  • 嵌套路由与布局路由:支持多层嵌套路由、辅助 Outlet(Auxiliary Router Outlet)和布局路由模式
  • 路由复用策略RouteReuseStrategy 控制组件在导航时的复用/重建行为
  • 异步重定向:v20+ 的 redirectTo 支持异步函数,可基于服务调用决定重定向目标
  • 导航取消 API:v20+ 的 Router.getCurrentNavigation()?.abort() 和 v20.2+ 的 currentNavigation Signal
  • SSR 路由渲染:配合 Angular SSR 支持按路由配置服务端/客户端渲染策略
  • 滚动恢复:内置滚动位置恢复和锚点平滑滚动
  • 路由标题策略TitleStrategy 动态设置页面标题,支持 SEO
  • 自定义 URL 匹配UrlMatcher 函数支持非标准 URL 匹配规则
  • Zoneless 兼容:v20.2+ Router 在 Zoneless 应用中完全稳定运行

生态图

关键依赖

  • @angular/core:Angular 核心框架(依赖注入、变更检测、Signals)
  • @angular/common:通用工具(Location 服务、LocationStrategy)
  • rxjs:响应式编程库(路由事件流、守卫/解析器返回值)
  • zone.js:变更检测基础(Zoneless 模式下不需要)

Angular 生态整合

  • Angular CLI:项目脚手架,自动生成路由配置和守卫文件
  • Angular DevTools:浏览器扩展,路由树可视化、导航追踪
  • Angular SSR / Angular DevKit:服务端渲染,增量水合(Incremental Hydration)
  • Angular Material:UI 组件库,与路由动画集成
  • Nx:企业级 Angular Monorepo 工具,路由生成器和模块联邦支持

相关插件与扩展

插件功能
@ngrx/router-storeNgRx 状态管理与路由状态同步
ngx-quicklinkQuicklinkStrategy,基于视口可见性智能预加载
@ngx-loading-bar/router路由切换时的顶部加载进度条
@ngx-translate/core多语言国际化与路由集成
@angular/service-workerPWA 路由缓存与离线支持
angular-sentry路由错误上报与追踪
@ngneat/transloco高性能国际化方案的路由集成

社区生态

  • 大量企业级权限控制方案(角色守卫、权限守卫、多因素认证守卫)
  • 多语言路由方案(URL 前缀 /zh/、子域名路由)
  • 路由级代码分割与 Module Federation 微前端
  • Google Analytics / Mixpanel 路由追踪集成
  • OpenTelemetry 路由导航追踪(2026年新增方案)

适用场景

  • Angular 企业级应用:Angular Router 是 Angular 项目的唯一路由方案,深度集成依赖注入和变更检测
  • 大型后台管理系统:多层嵌套路由、canMatch + canActivate 实现精细权限控制、loadChildren 实现模块懒加载
  • 多角色/多权限系统:函数式守卫组合实现 RBAC/ABAC 权限模型,canMatch 控制路由可见性
  • 复杂表单流程canDeactivate 守卫防止意外丢失未保存数据,支持多步骤向导流程
  • 微前端架构:Angular Module Federation + Angular Router 组合,实现独立部署的子应用路由
  • PWA 应用:与 Service Worker 配合的离线路由支持和缓存策略
  • 多语言国际化应用:路由级语言前缀、TitleStrategy 本地化标题
  • SSR/SSG 应用:Angular SSR 按路由配置渲染策略,配合增量水合优化首屏性能

开发与工程化

开发流程

# 创建项目(含路由)
ng new my-app --routing --style=scss
 
# 开发服务器
ng serve
 
# 构建(开发环境)
ng build
 
# 生产构建(含 AOT、Tree-shaking、代码压缩)
ng build --configuration production
 
# 运行测试
ng test
 
# E2E 测试
ng e2e
 
# 分析构建产物
ng build --stats-json && npx webpack-bundle-analyzer dist/my-app/stats.json

推荐项目结构

src/
├── app/
│   ├── app.routes.ts            # 根路由配置
│   ├── app.config.ts            # 应用配置(provideRouter)
│   ├── app.component.ts         # 根组件
│   ├── features/                # 功能模块
│   │   ├── home/
│   │   │   ├── home.component.ts
│   │   │   └── home.routes.ts   # 功能路由
│   │   ├── users/
│   │   │   ├── users.routes.ts
│   │   │   ├── resolvers/
│   │   │   │   └── user.resolver.ts
│   │   │   └── components/
│   │   └── admin/
│   │       ├── admin.routes.ts
│   │       └── guards/
│   ├── shared/                  # 共享资源
│   │   ├── guards/
│   │   │   ├── auth.guard.ts
│   │   │   └── role.guard.ts
│   │   └── resolvers/
│   └── layouts/                 # 布局组件
│       ├── main-layout.component.ts
│       └── auth-layout.component.ts
├── environments/
└── main.ts

布局路由模式

// app.routes.ts — 使用布局路由组织不同区域的页面
export const routes: Routes = [
  {
    path: '',
    loadComponent: () =>
      import('./layouts/main-layout.component').then(m => m.MainLayoutComponent),
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      {
        path: 'home',
        loadChildren: () =>
          import('./features/home/home.routes').then(m => m.HOME_ROUTES),
      },
      {
        path: 'users',
        loadChildren: () =>
          import('./features/users/users.routes').then(m => m.USER_ROUTES),
      },
    ],
  },
  {
    // 登录/注册使用独立布局(无侧边栏/导航)
    path: '',
    loadComponent: () =>
      import('./layouts/auth-layout.component').then(m => m.AuthLayoutComponent),
    children: [
      {
        path: 'login',
        loadComponent: () =>
          import('./features/auth/login.component').then(m => m.LoginComponent),
      },
    ],
  },
  { path: '**', redirectTo: 'home' },
]

路由测试

import { TestBed, fakeAsync, tick } from '@angular/core/testing'
import { provideRouter, Router } from '@angular/router'
import { provideLocationMocks } from '@angular/common/testing'
import { AppComponent } from './app.component'
 
describe('Routing', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [
        provideRouter([
          { path: '', redirectTo: '/home', pathMatch: 'full' },
          { path: 'home', component: AppComponent },
        ]),
        provideLocationMocks(),
      ],
    }).compileComponents()
  })
 
  it('should navigate to home', fakeAsync(() => {
    const router = TestBed.inject(Router)
    const fixture = TestBed.createComponent(AppComponent)
 
    router.navigate(['/home'])
    tick()
    fixture.detectChanges()
 
    expect(router.url).toBe('/home')
  }))
})

CI/CD 集成

  • 构建部署:Angular CLI 标准构建流程,ng build --configuration production
  • Nginx 配置:需要配置 try_files $uri $uri/ /index.html 以支持 SPA 路由
  • Docker 多阶段构建:Node.js 构建 + Nginx 运行
  • SSR 部署:Angular SSR 需要 Node.js 运行服务器
  • CDN 配置:静态资源使用 CDN,index.html 从源站返回

性能与安全

性能特点

  • 懒加载代码分割:按需加载路由组件/模块,初始包体积可减少 50-70%
  • 预加载策略:空闲时预加载后续可能需要的路由模块,消除二次导航延迟
  • 路由复用RouteReuseStrategy 避免组件重复创建销毁,缓存复杂页面状态
  • AOT 编译:生产构建自动进行 Ahead-of-Time 编译,减小运行时开销
  • Tree-shaking:Angular CLI 自动移除未使用代码

优化建议

  • 对所有非根路由使用 loadComponentloadChildren,避免初始包过大
  • 使用 PreloadAllModules(内网)或 QuicklinkStrategy(公网)预加载
  • 结合 ChangeDetectionStrategy.OnPush 减少路由变化引起的全树变更检测
  • 使用 runGuardsAndResolvers 控制守卫/解析器的触发条件(如仅参数变化时触发)
  • SSR 场景使用 TransferState 避免客户端重复获取 Resolve 数据
  • 使用 withComponentInputBinding() 替代手动订阅 ActivatedRoute.params,减少内存泄漏风险
  • 使用 takeUntilDestroyed() 管理路由相关订阅的生命周期

安全注意事项

  • 路由鉴权非安全屏障canActivate 守卫仅是前端 UX 优化,真正的安全验证必须在服务端/API 层实现
  • XSS 防护:Angular 默认转义模板输出,但 bypassSecurityTrust* 系列方法需要谨慎使用
  • CSRF 防护:Angular 提供 HttpClientXsrfModule 处理 CSRF Token
  • 路由参数验证:对用户输入的路由参数(:idqueryParams)进行类型和范围验证
  • 开放重定向防护:登录后的 returnUrl 重定向需要白名单验证,防止钓鱼攻击
  • 敏感路由 noindex:登录后页面、管理页面设置 noindex 防止搜索引擎索引

已知性能瓶颈

  • 大量路由配置的初始解析时间(数百条路由时可能影响启动速度)
  • 复杂守卫逻辑(如多个异步 API 调用)可能阻塞导航
  • 深层嵌套路由的递归变更检测(配合 OnPush 缓解)
  • 懒加载模块的首次导航延迟(可通过预加载缓解)
  • RouteReuseStrategy 使用不当导致内存泄漏(缓存组件未释放)
  • Router.events 订阅未取消导致的内存泄漏

技术对比

特性Angular Router (v22)React Router v7Vue Router 4TanStack Router
框架绑定Angular 专属React 专属Vue 3 专属React 专属
内置/独立框架内置独立库独立库(官方推荐)独立库
包体积~55KB gzipped~45KB gzipped~18KB gzipped~30KB gzipped
懒加载✅ 组件级 + 路由树级✅ 组件级✅ 组件级✅ 组件级
路由守卫✅ 五种内置守卫⚠️ 需 loader 手动实现✅ 全局/路由/组件三层✅ beforeLoad
预加载策略✅ 可定制策略 + Quicklink✅ prefetch 意图预加载❌ 无内置策略✅ 悬停/意图预加载
数据预取✅ Resolve 守卫✅ Loader API❌ 需手动实现✅ Loader API
路由动画✅ View Transitions API❌ 需 CSS/第三方✅ Transition 组件❌ 需 CSS
响应式事件✅ RxJS 完整事件流❌ 无❌ 无❌ 无
类型安全路由路径⚠️ 字符串路径⚠️ 部分泛型⚠️ 部分泛型✅ 端到端类型安全
Signal 集成✅ currentNavigation Signal❌ 无⚠️ 实验性❌ 无
SSR 支持✅ Angular SSR + 增量水合✅ 完整(框架级)⚠️ 基础✅ 支持
导航取消✅ abort() API⚠️ 需手动❌ 无❌ 无
学习曲线较陡中等
社区生态企业级方案丰富生态最大中等规模快速增长

最佳实践

路由模块化与懒加载

// ✅ 推荐:按功能模块拆分路由,全部使用懒加载
export const routes: Routes = [
  {
    path: '',
    loadComponent: () =>
      import('./layouts/main-layout.component').then(m => m.MainLayoutComponent),
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      {
        path: 'home',
        loadChildren: () =>
          import('./features/home/home.routes').then(m => m.HOME_ROUTES),
      },
      {
        path: 'users',
        loadChildren: () =>
          import('./features/users/users.routes').then(m => m.USER_ROUTES),
      },
    ],
  },
  { path: '**', redirectTo: 'home' },
]

函数式守卫组合

// ✅ 推荐:使用函数式守卫 + inject() + 组合模式
const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService)
  const router = inject(Router)
 
  if (!authService.isAuthenticated()) {
    return router.createUrlTree(['/login'], {
      queryParams: { returnUrl: state.url },
    })
  }
  return true
}
 
const adminGuard: CanActivateFn = () => {
  const authService = inject(AuthService)
  const router = inject(Router)
  return authService.user()?.role === 'admin'
    ? true
    : router.createUrlTree(['/forbidden'])
}
 
// 路由配置中组合多个守卫
{
  path: 'admin',
  canActivate: [authGuard, adminGuard],
  loadChildren: () => import('./admin.routes').then(m => m.ADMIN_ROUTES),
}

数据预取与组件输入绑定

// ✅ 推荐:使用 Resolve + withComponentInputBinding 替代手动订阅
const userResolver: ResolveFn<User> = (route) => {
  const userService = inject(UserService)
  return userService.getUser(route.paramMap.get('id')!)
}
 
// 路由配置
{
  path: 'users/:id',
  resolve: { user: userResolver },
  loadComponent: () =>
    import('./user-detail.component').then(m => m.UserDetailComponent),
}
 
// 组件 — 通过 @Input 直接接收路由参数和 Resolve 数据
@Component({ /* ... */ })
export class UserDetailComponent {
  @Input() id!: string    // 来自路由参数 :id
  @Input() user!: User    // 来自 resolve: { user: userResolver }
}
 
// ✅ v17+ 更推荐:使用 Signal input
@Component({ /* ... */ })
export class UserDetailComponent {
  id = input.required<string>()
  user = input.required<User>()
}

导航事件与加载状态

// ✅ 推荐:使用 currentNavigation Signal(v20.2+)追踪导航状态
@Component({
  selector: 'app-loading-bar',
  template: `<div class="bar" [class.active]="isNavigating()"></div>`,
})
export class LoadingBarComponent {
  private router = inject(Router)
 
  isNavigating = computed(() => this.router.currentNavigation() !== null)
}

常见陷阱

  • 不要使用 component 替代 loadComponent(失去懒加载能力,增大初始包体积)
  • 不要忽略 pathMatch: 'full'(空路径重定向缺少它会导致所有路由匹配)
  • 不要在守卫中执行耗时同步操作(阻塞 UI 线程)
  • 不要忘记取消 Router.eventsActivatedRoute.params 的订阅(使用 takeUntilDestroyed()
  • 不要RouteReuseStrategy 中缓存过多组件(导致内存泄漏)
  • 不要将前端路由守卫当作安全屏障(服务端必须做权限校验)
  • 不要canDeactivate 中依赖已被销毁的组件引用
  • 不要混用 RouterModule.forRoot()provideRouter()(选一种配置方式)

技术局限与边界

已知限制

  • Angular 专属:只能用于 Angular 项目,无法跨框架复用路由逻辑
  • 学习曲线陡峭:概念体系复杂(模块、守卫、解析器、预加载策略、复用策略、URL 匹配器等)
  • 包体积较大:相比 Vue Router(~18KB)等,Angular Router 体积较大(~55KB),但这是 Angular 整体体积的一部分
  • 路由路径无编译期类型安全:路径是字符串字面量,重构时可能遗漏(TanStack Router 提供了端到端类型安全)
  • 与 Angular 版本强绑定:路由 API 随框架版本升级变化,大版本迁移需要同步更新路由配置
  • Zone.js 依赖:传统模式下依赖 Zone.js 触发变更检测(v20.2+ 支持 Zoneless 但仍在演进中)

不适用场景

  • 非 Angular 项目(React/Vue/Svelte 等框架)
  • 极简单的单页面应用(1-3 个页面,无导航需求)
  • 对包体积极度敏感的边缘场景(Angular 整体包体积较大)
  • 需要跨框架共享路由逻辑的微前端场景(需用其他方案处理路由协调)
  • 需要端到端类型安全路由路径的场景(TanStack Router 更优)

迁移注意事项

迁移方向要点
NgModule → StandaloneRouterModule.forRoot()provideRouter(),移除 @NgModule 装饰器
类守卫 → 函数守卫CanActivate 类 → CanActivateFn 函数,使用 inject() 获取依赖
canLoadcanMatchv14.2+ 废弃 canLoad,使用 canMatch 替代
getCurrentNavigation() → Signalv20.2+ 废弃方法,使用 router.currentNavigation Signal
手动订阅 → 输入绑定使用 withComponentInputBinding() 替代手动订阅 ActivatedRoute.params
Angular 版本升级每个大版本检查废弃 API 和 Breaking Changes

学习资源

官方文档

教程

社区资源

2026 年现状

最新版本

  • Angular 22.0.5(2026年6月3日发布)— 当前最新稳定版
  • @angular/router 22.0.5 — 与框架同步发版
  • Angular 21.x(2025年11月)— 仍在 LTS 支持期内
  • Angular 20.x(2025年5月)— LTS 支持中
  • Angular 19.x — 已于 2026年5月到达 EOL

发展趋势

  • Signals 全面渗透:路由状态(currentNavigation)、URL 激活追踪(isActive)、表单集成(Signal Forms)全面 Signal 化
  • Zoneless 稳定化:Router 在 Zoneless 模式下完全稳定,不再依赖 zone.js
  • SSR + 增量水合:Angular SSR 持续增强,按路由配置渲染策略,增量水合稳定后进一步提升首屏性能
  • View Transitions 成熟:浏览器原生 View Transitions API 在更多浏览器中支持,Angular Router 集成日趋成熟
  • AI 工具集成:Angular CLI 内置 MCP 配置生成,AI 辅助路由配置和调试

社区活跃度

  • GitHub Stars(Angular 整体):约 98k+
  • npm 周下载量(@angular/router):约 350 万+
  • 贡献者(Angular 整体):2000+
  • 更新频率:每 6 个月一个主版本(5月/11月)
  • Angular v22 被社区评价为"2026年最佳 JavaScript 框架更新之一"

未来路线图

  • Signals 在路由模块中的全面应用(路由配置 Signal 化)
  • 更简洁的路由配置 API 和类型安全增强
  • SSR 和增量水合的持续改进,支持更多渲染策略
  • 浏览器 View Transitions API 跨浏览器兼容完善
  • 开发工具(DevTools)路由可视化增强
  • 与 Angular 框架统一演进,保持 6 个月发版节奏