站长资讯网
最全最丰富的资讯网站

浅析Angular路由中的懒加载、守卫、动态参数

浅析Angular路由中的懒加载、守卫、动态参数

路由是将URL请求映射到具体代码的一种机制,在网站的模块划分、信息架构中扮演了重要的角色,而Angular的路由能力非常强大,我们一起来看看吧。【相关教程推荐:《angular教程》】

路由懒加载

Angular可以根据路由,动态加载相应的模块代码,这个功能是性能优化的利器。

为了加快首页的渲染速度,我们可以设计如下的路由,让首页尽量保持简洁、清爽:

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动态加载。

效果如下:

浅析Angular路由中的懒加载、守卫、动态参数

其中的components-list-list-module-ngfactory.js文件,只有当访问/list路由时才会加载。

路由守卫

当我们访问或切换路由时,会加载相应的模块和组件,路由守卫可以理解为在路由加载前后的钩子,最常见的是进入路由的守卫和离开路由的守卫:

  • canActivate 进入守卫
  • canDeactivate 离开守卫

比如我们想在用户进入详情页之前,判断他是否有权限,就可以使用canActivate守卫。

增加路由守卫

{   path: 'detail',   loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),    // 路由守卫   canActivate: [AuthGuard], },

编写守卫逻辑

使用CLI命令创建路由守卫模块:

ng g guard auth

auth.guard.ts

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:

ng g s detail

detail.service.ts

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');   } }

效果如下:

浅析Angular路由中的懒加载、守卫、动态参数

由于我们对/detail路由增加了守卫,不管是从别的路由切换到/detail路由,还是直接访问/detail路由,都无法进入该页面。

动态路由参数

在路由中带参数有很多中方法:

  • 在path中带参数
  • 在queryString中带参数
  • 不通过链接带参数

在path中带参

{   path: 'user/:id',   loadChildren: () => import('./components/user/user.module').then(m => m.UserModule), },

在queryString中带参数

html传参

<a [routerLink]="['/list']" [queryParams]="{id: '1'}">...</a>

ts传参

this.router.navigate(['/list'],{ queryParams: { id: '1' });

通过data传递静态参数

注意:通过data传递的路由参数只能是静态的

{   path: 'detail',   loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),      // 静态参数   data: {     title: '详情'   } },

通过resolve传递动态参数

data只能传递静态参数,那我想通过路由传递从后台接口获取到的动态参数,该怎么办呢?

答案是通过resolve配置。

{   path: 'detail',   loadChildren: () => import('./components/detail/detail.module').then(m => m.DetailModule),      // 动态路由参数   resolve: {     detail: DetailResolver   }, },

创建Resolver

detail.resolver.ts

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

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');   } }

获取动态参数

创建组件

ng g c detial

detail.component.ts

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);   }  }

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号