本文摘自PHP中文网,作者青灯夜游,侵删。

路由是将URL请求映射到具体代码的一种机制,在网站的模块划分、信息架构中扮演了重要的角色,而Angular的路由能力非常强大,我们一起来看看吧。【相关教程推荐:《angular教程》】
路由懒加载
Angular可以根据路由,动态加载相应的模块代码,这个功能是性能优化的利器。
为了加快首页的渲染速度,我们可以设计如下的路由,让首页尽量保持简洁、清爽:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const routes: Routes = [
{
path: '' ,
children: [
{
path: 'list' ,
loadChildren: () => import( './components/list/list.module' ).then(m => m.ListModule),
},
{
path: 'detail' ,
loadChildren: () => import( './components/detail/detail.module' ).then(m => m.DetailModule),
},
...
],
},
];
|
首页只有一些简单的静态元素,而其他页面,比如列表、详情、配置等模块都用loadChildren
动态加载。
效果如下:

其中的components-list-list-module-ngfactory.js
文件,只有当访问/list
路由时才会加载。
路由守卫
当我们访问或切换路由时,会加载相应的模块和组件,路由守卫可以理解为在路由加载前后的钩子,最常见的是进入路由的守卫和离开路由的守卫:
- canActivate 进入守卫
- canDeactivate 离开守卫
比如我们想在用户进入详情页之前,判断他是否有权限,就可以使用canActivate
守卫。
增加路由守卫
1 2 3 4 5 6 7 | {
path: 'detail' ,
loadChildren: () => import( './components/detail/detail.module' ).then(m => m.DetailModule),
canActivate: [AuthGuard],
},
|
编写守卫逻辑
使用CLI命令创建路由守卫模块:
auth.guard.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import { Injectable } from '@angular/core' ;
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router' ;
import { Observable } from 'rxjs' ;
import { DetailService } from './detail.service' ;
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private detailService: DetailService,
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return new Observable(observer => {
this .detailService.getDetailAuth().subscribe((hasPermission: boolean) => {
observer.next(hasPermission);
observer.complete();
});
});
}
}
|
获取权限service
获取权限的service:
detail.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 | import {Injectable} from '@angular/core' ;
import { HttpClient } from '@angular/common/http' ;
@Injectable({ providedIn: 'root' })
export class DetailService {
constructor(
private http: HttpClient,
) { }
getDetailAuth(): any {
return this .http.get( '/detail/auth' );
}
}
|
效果如下:

由于我们对/detail
路由增加了守卫,不管是从别的路由切换到/detail
路由,还是直接访问/detail
路由,都无法进入该页面。
动态路由参数
在路由中带参数有很多中方法:
- 在path中带参数
- 在queryString中带参数
- 不通过链接带参数
在path中带参
1 2 3 4 | {
path: 'user/:id' ,
loadChildren: () => import( './components/user/user.module' ).then(m => m.UserModule),
},
|
在queryString中带参数
html传参
1 | <a [routerLink]= "['/list']" [queryParams]= "{id: '1'}" >...</a>
|
ts传参
1 | this .router.navigate([ '/list' ],{ queryParams: { id: '1' });
|
通过data传递静态参数
注意:通过data传递的路由参数只能是静态的
1 2 3 4 5 6 7 8 9 | {
path: 'detail' ,
loadChildren: () => import( './components/detail/detail.module' ).then(m => m.DetailModule),
data: {
title: '详情'
}
},
|
通过resolve传递动态参数
data只能传递静态参数,那我想通过路由传递从后台接口获取到的动态参数,该怎么办呢?
答案是通过resolve
配置。
1 2 3 4 5 6 7 8 9 | {
path: 'detail' ,
loadChildren: () => import( './components/detail/detail.module' ).then(m => m.DetailModule),
resolve: {
detail: DetailResolver
},
},
|
创建Resolver
detail.resolver.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 | import { Injectable } from '@angular/core' ;
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router' ;
import { DetailService } from './detail.service' ;
@Injectable({ providedIn: 'root' })
export class DetailResolver implements Resolve<any> {
constructor(private detailService: DetailService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
return this .detailService.getDetail();
}
}
|
在服务中增加获取详情数据的方法
detail.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import {Injectable} from '@angular/core' ;
import { HttpClient } from '@angular/common/http' ;
@Injectable({ providedIn: 'root' })
export class DetailService {
constructor(
private http: HttpClient,
) { }
getDetailAuth(): any {
return this .http.get( '/detail/auth' );
}
getDetail(): any {
return this .http.get( '/detail' );
}
}
|
获取动态参数
创建组件
detail.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import { Component, OnInit } from '@angular/core' ;
import { ActivatedRoute } from '@angular/router' ;
@Component({
selector: 'app-detail' ,
templateUrl: './detail.component.html' ,
styleUrls: [ './detail.component.scss' ]
})
export class DetailComponent implements OnInit {
constructor(
private route: ActivatedRoute,
) { }
ngOnInit(): void {
const detail = this .route.snapshot.data.detail;
console.log( 'detail:' , detail);
}
}
|
更多编程相关知识,请访问:编程视频!!
以上就是浅析Angular路由中的懒加载、守卫、动态参数的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
浅谈Angular中控制器、服务和指令的关系
详解Angular中的route路由
聊聊Angular项目中将 .css 文件修改为 .scss 文件的方法
Angular cli中的在线和离线安装
Angular与Angularjs的简单比较
如何利用管道提高Angular应用程序的性能?
vue中路由之间如何通讯?方法介绍
Angular组件怎么进行通信?父子组件通信的2种方法
浅谈Angular中@viewchild的用法
浅谈Angular中父子组件间相互传参的方法
更多相关阅读请进入《Angular》频道 >>
人民邮电出版社
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者
转载请注明出处:木庄网络博客 » 浅析Angular路由中的懒加载、守卫、动态参数