angular-router

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

@angular/router

@angular/router

Version: Angular 21 (2025) Tags: Routing, Navigation, Guards, Lazy Loading, SPA
References: Docs — official routing guide • APIGitHub
版本: Angular 21 (2025) 标签: Routing, Navigation, Guards, Lazy Loading, SPA
参考资料: 官方文档 — 官方路由指南 • API文档GitHub仓库

API Changes

API变更

This section documents recent version-specific API changes.
  • NEW: Functional guards and resolvers — Prefer functional approach over class-based guards source
  • NEW: Router inputs — New way to pass data to components via route inputs source
  • NEW: withComponentInputBinding — Enable component input binding from route params
  • NEW: Router snapshots improvement — Better type safety for route parameters
  • NEW: provideRouter() — Modern router configuration with functional providers
  • DEPRECATED: RouterModule.forRoot() — Use provideRouter() in modern applications
本节记录了近期版本专属的API变动情况。
  • 新特性:函数式守卫与解析器 — 优先使用函数式方案,而非基于类的守卫 来源
  • 新特性:Router inputs — 通过路由输入向组件传递数据的新方式 来源
  • 新特性:withComponentInputBinding — 启用从路由参数到组件输入的绑定
  • 新特性:Router snapshots优化 — 为路由参数提供更好的类型安全
  • 新特性:provideRouter() — 基于函数式提供者的现代化路由配置方案
  • 已废弃:RouterModule.forRoot() — 现代应用请使用provideRouter()

Best Practices

最佳实践

  • Use lazy loading for feature modules — Reduce initial bundle size by 50-70%
ts
const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.routes').then(m => m.DASHBOARD_ROUTES)
  }
];
  • Use functional guards over class-based guards
ts
// ✅ Modern functional guard
const authGuard = () => {
  const authService = inject(AuthService);
  const router = inject(Router);
  
  if (authService.isAuthenticated()) {
    return true;
  }
  return router.createUrlTree(['/login']);
};

// ❌ Avoid class-based guards for new code
// @Injectable() export class AuthGuard implements CanActivate { ... }
  • Use CanMatch guard for lazy-loaded routes — Prevents unauthorized code downloads
ts
{
  path: 'admin',
  canMatch: [authGuard],
  loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent)
}
  • Use resolvers for pre-fetching data — Eliminates loading spinners
ts
{
  path: 'user/:id',
  resolve: { user: userResolver }
}

// In component
@Component({})
export class UserComponent {
  private route = inject(ActivatedRoute);
  
  // Modern way
  user = input.required<User>();
  
  // Legacy way
  ngOnInit() {
    this.route.data.subscribe(data => {
      this.user = data['user'];
    });
  }
}
  • Use router inputs for better type safety
ts
// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withComponentInputBinding())
  ]
};

// Component receives route params as inputs
@Component({})
export class UserComponent {
  @Input() id!: string;
}
  • Use wildcard routes for 404 pages
ts
{
  path: '**',
  component: NotFoundComponent
}
  • Use PreloadAllModules for background loading
ts
provideRouter(routes, withPreloading(PreloadAllModules))
  • Use routerLink for navigation — Maintains SPA behavior
ts
// ✅ Correct
<a routerLink="/dashboard">Dashboard</a>

// ❌ Wrong - causes full page reload
<a href="/dashboard">Dashboard</a>
  • Use kebab-case for URL paths — Consistent naming convention
ts
// ✅ Good
{ path: 'user-profile', ... }

// ❌ Avoid
{ path: 'userProfile', ... }
  • 对功能模块使用懒加载 — 可将初始包体积减小50-70%
ts
const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.routes').then(m => m.DASHBOARD_ROUTES)
  }
];
  • 优先使用函数式守卫,而非基于类的守卫
ts
// ✅ 现代化函数式守卫
const authGuard = () => {
  const authService = inject(AuthService);
  const router = inject(Router);
  
  if (authService.isAuthenticated()) {
    return true;
  }
  return router.createUrlTree(['/login']);
};

// ❌ 新代码请避免使用基于类的守卫
// @Injectable() export class AuthGuard implements CanActivate { ... }
  • 为懒加载路由使用CanMatch守卫 — 可防止未授权的代码下载
ts
{
  path: 'admin',
  canMatch: [authGuard],
  loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent)
}
  • 使用resolvers预取数据 — 消除加载动画
ts
{
  path: 'user/:id',
  resolve: { user: userResolver }
}

// 组件中使用
@Component({})
export class UserComponent {
  private route = inject(ActivatedRoute);
  
  // 现代化用法
  user = input.required<User>();
  
  // 传统用法
  ngOnInit() {
    this.route.data.subscribe(data => {
      this.user = data['user'];
    });
  }
}
  • 使用router inputs获得更好的类型安全
ts
// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withComponentInputBinding())
  ]
};

// 组件接收路由参数作为输入
@Component({})
export class UserComponent {
  @Input() id!: string;
}
  • 为404页面使用通配符路由
ts
{
  path: '**',
  component: NotFoundComponent
}
  • 使用PreloadAllModules实现后台预加载
ts
provideRouter(routes, withPreloading(PreloadAllModules))
  • 使用routerLink实现导航 — 保持SPA行为
ts
// ✅ 正确用法
<a routerLink="/dashboard">Dashboard</a>

// ❌ 错误用法 - 会导致页面全量重载
<a href="/dashboard">Dashboard</a>
  • URL路径使用短横线命名法 — 统一命名规范
ts
// ✅ 推荐
{ path: 'user-profile', ... }

// ❌ 不推荐
{ path: 'userProfile', ... }