angular-guards
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAngular Route Guards
Angular Route Guards
Version: Angular 21 (2025)
Tags: Guards, Routing, Auth, CanActivate
References: Guards Guide • CanActivate
版本: Angular 21 (2025)
标签: Guards, Routing, Auth, CanActivate
参考资料: Guards Guide • CanActivate
API Changes
API 变更
This section documents recent version-specific API changes.
-
NEW: Functional guards — Useinstead of class-based
CanActivateFn -
NEW: CanMatch guard — Prevent lazy loading of unauthorized code
-
NEW: provideRouter with guards — Modern guard registration
-
DEPRECATED: Class-based guards — Migrate to functional
本部分记录了近期特定版本的API变更:
-
新增:函数式守卫 —— 请使用替代基于类的守卫
CanActivateFn -
新增:CanMatch 守卫 —— 阻止未授权代码的懒加载
-
新增:带守卫的 provideRouter —— 现代化的守卫注册方式
-
已废弃:基于类的守卫 —— 请迁移至函数式实现
Best Practices
最佳实践
- Create functional guard
ts
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
return router.createUrlTree(['/login']);
};- Use CanActivate for route protection
ts
const routes: Routes = [
{
path: 'dashboard',
canActivate: [authGuard],
component: DashboardComponent
}
];- Use CanActivateChild for child routes
ts
export const adminGuard: CanActivateChildFn = () => {
const auth = inject(AuthService);
return auth.isAdmin() || inject(Router).createUrlTree(['/unauthorized']);
};
const routes: Routes = [
{
path: 'admin',
canActivateChild: [adminGuard],
children: [...]
}
];- Use CanMatch for lazy loading
ts
const routes: Routes = [
{
path: 'admin',
canMatch: [authGuard],
loadComponent: () => import('./admin/admin.component')
}
];- Use CanDeactivate for unsaved changes
ts
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => {
if (component.hasUnsavedChanges?.()) {
return confirm('You have unsaved changes. Are you sure?');
}
return true;
};- Use withComponentInputBinding
ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withComponentInputBinding())
]
};- Use multiple guards
ts
const routes: Routes = [
{
path: 'admin',
canActivate: [authGuard, adminGuard],
loadComponent: () => import('./admin/admin.component')
}
];- Pass data to guards
ts
const routes: Routes = [
{
path: 'user/:id',
canActivate: [userGuard],
data: { requiredRole: 'admin' }
}
];
export const userGuard: CanActivateFn = (route, state) => {
const requiredRole = route.data['requiredRole'];
// Check role
};- 创建函数式守卫
ts
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
return router.createUrlTree(['/login']);
};- 使用 CanActivate 实现路由保护
ts
const routes: Routes = [
{
path: 'dashboard',
canActivate: [authGuard],
component: DashboardComponent
}
];- 子路由使用 CanActivateChild
ts
export const adminGuard: CanActivateChildFn = () => {
const auth = inject(AuthService);
return auth.isAdmin() || inject(Router).createUrlTree(['/unauthorized']);
};
const routes: Routes = [
{
path: 'admin',
canActivateChild: [adminGuard],
children: [...]
}
];- 懒加载场景使用 CanMatch
ts
const routes: Routes = [
{
path: 'admin',
canMatch: [authGuard],
loadComponent: () => import('./admin/admin.component')
}
];- 未保存变更场景使用 CanDeactivate
ts
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => {
if (component.hasUnsavedChanges?.()) {
return confirm('You have unsaved changes. Are you sure?');
}
return true;
};- 使用 withComponentInputBinding
ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withComponentInputBinding())
]
};- 搭配使用多个守卫
ts
const routes: Routes = [
{
path: 'admin',
canActivate: [authGuard, adminGuard],
loadComponent: () => import('./admin/admin.component')
}
];- 向守卫传递数据
ts
const routes: Routes = [
{
path: 'user/:id',
canActivate: [userGuard],
data: { requiredRole: 'admin' }
}
];
export const userGuard: CanActivateFn = (route, state) => {
const requiredRole = route.data['requiredRole'];
// Check role
};