主题
Angular 路由与导航:构建单页应用的核心技术
更新: 9/4/2025字数: 0 字 时长: 0 分钟
路由是Angular单页应用(SPA)的核心机制,它允许我们在不重新加载整个页面的情况下切换视图。
一、路由基础配置
1. 基本路由设置
首先需要在主模块中配置路由:
typescript
import { RouterModule, Routes } from "@angular/router";
const routes: Routes = [
{ path: "", component: HomeComponent },
{ path: "products", component: ProductsComponent },
{ path: "products/:id", component: ProductDetailComponent },
{ path: "about", component: AboutComponent },
{ path: "**", component: NotFoundComponent } // 404页面
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}2. 路由出口
在根组件模板中添加<router-outlet>:
html
<!-- app.component.html -->
<app-header></app-header>
<router-outlet></router-outlet>
<!-- 路由内容将在这里渲染 -->
<app-footer></app-footer>二、导航方式
1. 模板导航
使用routerLink指令:
html
<a routerLink="/">首页</a>
<a routerLink="/products">产品列表</a>
<a [routerLink]="['/products', product.id]">产品详情</a>2. 编程式导航
在组件类中使用Router服务:
typescript
import { Router } from '@angular/router';
constructor(private router: Router) {}
navigateToProduct(id: number) {
this.router.navigate(['/products', id]);
// 或者带查询参数
this.router.navigate(['/products'], {
queryParams: { category: 'electronics' }
});
}三、路由参数获取
1. 路径参数
typescript
import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) {}
ngOnInit() {
// 获取路径参数
const id = this.route.snapshot.paramMap.get('id');
// 或者监听参数变化
this.route.paramMap.subscribe(params => {
this.productId = params.get('id');
});
}2. 查询参数
typescript
// 获取查询参数
this.route.queryParamMap.subscribe((params) => {
this.category = params.get("category");
});
// 导航时添加查询参数
this.router.navigate(["/products"], {
queryParams: { category: "books" }
});四、高级路由功能
1. 路由守卫
认证守卫示例:
typescript
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.auth.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
// 在路由配置中使用
{
path: 'admin',
component: AdminPanelComponent,
canActivate: [AuthGuard]
}2. 懒加载模块
typescript
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module')
.then(m => m.DashboardModule)
}3. 预加载策略
typescript
@NgModule({
imports: [
RouterModule.forRoot(routes, {
preloadingStrategy: PreloadAllModules
})
]
})
export class AppRoutingModule {}五、路由动画
1. 配置路由动画
typescript
import { trigger, transition, style, animate } from "@angular/animations";
export const routeAnimations = trigger("routeAnimations", [
transition("* <=> *", [style({ opacity: 0 }), animate("300ms ease-in", style({ opacity: 1 }))])
]);2. 在组件中使用
typescript
@Component({
selector: "app-root",
template: `
<div [@routeAnimations]="prepareRoute(outlet)">
<router-outlet #outlet="outlet"></router-outlet>
</div>
`,
animations: [routeAnimations]
})
export class AppComponent {
prepareRoute(outlet: RouterOutlet) {
return outlet?.activatedRouteData?.["animation"];
}
}六、常见问题解答
Q1: 如何实现嵌套路由?
typescript
{
path: 'products',
component: ProductsComponent,
children: [
{ path: '', component: ProductListComponent },
{ path: ':id', component: ProductDetailComponent }
]
}Q2: 如何获取路由事件?
typescript
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
console.log("导航开始");
}
if (event instanceof NavigationEnd) {
console.log("导航结束");
}
});Q3: 如何设置默认路由?
typescript
{ path: '', redirectTo: '/home', pathMatch: 'full' }