首頁  >  文章  >  web前端  >  淺析Angular路由中的懶加載、守衛、動態參數

淺析Angular路由中的懶加載、守衛、動態參數

青灯夜游
青灯夜游轉載
2021-07-01 11:05:592477瀏覽

淺析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 &#39;@angular/core&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;

@Injectable({ providedIn: &#39;root&#39; })
export class DetailService {
  constructor(
    private http: HttpClient,
  ) { }

  getDetailAuth(): any {
    return this.http.get(&#39;/detail/auth&#39;);
  }
}

效果如下:

淺析Angular路由中的懶加載、守衛、動態參數

由於我們對/detail路由增加了守衛,不管是從別的路由切換到/detail路由,還是直接存取/detail路由,都無法進入該頁面。

動態路由參數

在路由中帶參數有很多中方法:

  • #在path中帶參數
  • 在queryString中帶參數
  • 不透過連結帶參數

在path中帶參考

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

在queryString中帶參數

html傳參

<a [routerLink]="[&#39;/list&#39;]" [queryParams]="{id: &#39;1&#39;}">...</a>

ts傳參

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

透過data傳遞靜態參數

注意:透過data傳遞的路由參數只能是靜態的

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

透過resolve傳遞動態參數

data只能傳遞靜態參數,那我想透過路由傳遞從後台介面取得到的動態參數,該怎麼辦呢?

答案是透過resolve來配置。

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

建立Resolver

detail.resolver.ts

import { Injectable } from &#39;@angular/core&#39;;
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from &#39;@angular/router&#39;;
import { DetailService } from &#39;./detail.service&#39;;

@Injectable({ providedIn: &#39;root&#39; })
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 &#39;@angular/core&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;

@Injectable({ providedIn: &#39;root&#39; })
export class DetailService {
  constructor(
    private http: HttpClient,
  ) { }

  getDetailAuth(): any {
    return this.http.get(&#39;/detail/auth&#39;);
  }

  // 增加的
  getDetail(): any {
    return this.http.get(&#39;/detail&#39;);
  }
}

取得動態參數

建立元件

ng g c detial

detail.component.ts

import { Component, OnInit } from &#39;@angular/core&#39;;
import { ActivatedRoute } from &#39;@angular/router&#39;;

@Component({
  selector: &#39;app-detail&#39;,
  templateUrl: &#39;./detail.component.html&#39;,
  styleUrls: [&#39;./detail.component.scss&#39;]
})
export class DetailComponent implements OnInit {

  constructor(
    private route: ActivatedRoute,
  ) { }

  ngOnInit(): void {
    // 和获取静态参数的方式是一样的
    const detail = this.route.snapshot.data.detail;
    console.log(&#39;detail:&#39;, detail);
  }

}

更多程式相關知識,請造訪:程式設計影片! !

以上是淺析Angular路由中的懶加載、守衛、動態參數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除