本文深入解析 Angular 中 Router 模块的工作原理,涵盖路由注册、组件生命周期管理、延迟加载及预加载机制。详细演示了如何在 HTML 模板和 TypeScript 代码中实现页面跳转,并重点讲解了路径参数与查询参数的读取方法。此外,还探讨了 URL 格式化(Hash 模式与 HTML5 模式)及服务器部署时的配置技巧,帮助开发者掌握 Angular 路由的核心用法。
1. 摘要
简而言之,路由机制使得不同的 URL 地址对应展示不同的页面内容。同时,浏览器的前进和后退按钮能够基于浏览历史在页面间进行导航,这同样依赖于路由功能。
在 Angular 框架中,Router 是一个独立的模块,其定义位于 @angular/router 包内。
Router 模块能够与 NgModule 配合使用,实现模块的延迟加载(懒加载)或预加载功能(具体可参考《Angular入门到精通系列教程(11)- 模块(NgModule),延迟加载模块》)。
Router 负责管理组件的生命周期,包括组件的创建与销毁过程。
对于基于 Angular CLI 创建的新项目,在初始化时可以通过指定选项,将 AppRoutingModule 默认集成到 app.component.ts 文件中。
2. 路由(Router)基本用法
2.1. 准备
为了演示路由的使用,我们首先创建两个页面组件。
ng g c page1 ng g c page2
利用上述 Angular CLI 命令,可以分别创建 Page1Component 和 Page2Component 两个组件。
2.2. 注册路由
//src\app\app-routing.module.ts
const routes: Routes = [
{
path: 'page1',
component: Page1Component
},
{
path: 'page2',
component: Page2Component
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}观察可见,简单的路由注册仅需配置 path 和 component 两个属性,分别用于定义路由的相对路径以及该路径对应的响应组件。
2.3. html中的用法
<a routerLink="page1">Page1</a> |
<a routerLink="page2">Page2</a>在 HTML 模板中,可以直接使用 routerLink 属性来标识 Angular 路由。执行代码后,可以看到 Page1 和 Page2 两个超链接,点击它们会使地址栏地址变为 http://localhost:4200/page2 或 http://localhost:4200/page1,页面内容随之在 page1 和 page2 之间切换。
2.4. ts代码中的用法
有时需要根据 TypeScript 中的业务逻辑进行页面跳转。在 TS 代码中,需要注入 Router 实例,例如:
constructor(private router: Router) {}跳转代码示例如下:
// 跳转到 /page1
this.router.navigate(['/page1']);
// 跳转到 /page1/123
this.router.navigate(['/page1', 123]);3. 接收参数
3.1. 路径中的参数
通常,我们将参数作为 URL 的一部分,例如 /users/1 代表查询 ID 为 1 的用户,路由定义风格为 "/users/id"。
针对我们的简单页面场景,假设 page1 页面需要传递 id 参数,则需要修改路由配置如下:
const routes: Routes = [
{
path: 'page1/:id', //接收id参数
component: Page1Component,
},
{
// 实现可选参数的小技巧。 这个routing处理没有参数的url
path: 'page1',
redirectTo: 'page1/', // 跳转到'page1/:id'
},
{
path: 'page2',
component: Page2Component,
},
];在 TS 代码中读取参数时,首先需要注入 ActivatedRoute,代码如下:
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
this.activatedRoute.paramMap.subscribe((params) => {
console.log('Parameter id: ', params.get('id'));
// 地址 http://localhost:4200/page1/33
// 控制台输出:Query Parameter name: 33
// 地址 http://localhost:4200/page1/
// 控制台输出:Query Parameter name: (实际结果为undefined)
});
}3.2. 参数(QueryParameter)中的参数
参数还有另一种写法,例如 http://localhost:4200/?name=cat,即在 URL 地址后添加问号 '?',随后追加参数名和参数值('name=cat')。这种方式称为查询参数(QueryParameter)。
获取查询参数时,方法与之前的路由参数类似,只需将 paramMap 改为 queryParamMap,代码如下:
this.activatedRoute.queryParamMap.subscribe((params) => {
console.log('Query Parameter name: ', params.get('name'));
// 地址 http://localhost:4200/page1?name=cat
// 控制台输出:Query Parameter name: cat
// 地址 http://localhost:4200/page1/
// 控制台输出:Query Parameter name: (实际结果为undefined)
});4. URL路径显示格式
与传统的纯静态(HTML)站点不同,Angular 中的 URL 并不对应真实的文件(页面),因为 Angular 接管的路由(Routing)处理决定了向终端用户展示哪个 Component。为了适应不同场景,Angular 的 URL 路径显示格式主要有两种:
http://localhost:4200/page1/123
http://localhost:4200/#/page1/123
默认采用第一种,即不加 '#' 的形式。如果需要启用第二种形式,可以在 app-routing.ts 中加入 useHash: true,配置如下:
// app-routing.ts
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})5. 部署中遇到的问题
同样,由于 Angular 接管了路由(Routing)处理,因此在部署到 IIS、Nginx 等服务器时,会有不同的技巧和要求,详细参考:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
6. 总结
- Angular 默认不支持可选路由(例如 /user/:id?),但我们可以定义两个路由指向同一个 Component 来实现此功能,从而达到代码复用的目的(或者使用 redirectTo)。
- 可以使用 useHash 参数,实现在 Angular 路径前添加 '#'。
- 读取参数时,都需要通过 subscribe 订阅一下,不能直接读取。
- 打包后部署问题,查看官方 wiki(https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode)。
到此这篇关于 Angular 中针对路由 Routing 原理刨析的文章就介绍到这了,更多相关 Angular 路由 Routing 内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!