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

深入了解Angular中的路由

什么是路由?本篇文章带大家深入了解一下Angular中的路由,希望对大家有所帮助!

深入了解Angular中的路由

路由简介

路由是实现单页面应用的一种方式,通过监听hash或者history的变化,渲染不同的组件,起到局部更新的作用,避免每次URL变化都向服务器请求数据。【相关教程推荐:《angular教程》】

路由配置

配置路由模块:approuter.module.ts

const routes: Routes = [     { path: "first", component: FirstComponent },     { path: "parent", component: SecondComponent } ] @NgModule({     imports: [         CommonModule,         // RouterModule.forRoot方法会返回一个模块,其中包含配置好的Router服务         // 提供者,以及路由库所需的其它提供者。         RouterModule.forRoot(routes, {             // enableTracing: true, // <-- debugging purposes only             // 配置所有的模块预加载,也就是懒加载的模块,在系统空闲时,把懒加载模块加载进来             // PreloadAllModules 策略不会加载被CanLoad守卫所保护的特性区。             preloadingStrategy: PreloadAllModules           })     ],     exports: [         FirstComponent,         SecondComponent,         RouterModule     ],     declarations: [         FirstComponent,         SecondComponent     ] }) export class ApprouterModule { }

app.module.ts中引入改模块:

imports: [ ApprouterModule ]

重定向路由:

const routes: Routes = [     { path: "", redirectTo: "first", pathMatch: "full" } ]

通配符路由:

const routes: Routes = [     // 路由器会使用先到先得的策略来选择路由。 由于通配符路由是最不具体的那个,因此务必确保它是路由配置中的最后一个路由。     { path: "**", component: NotFoundComponent } ]

路由懒加载:

配置懒加载模块可以使得首屏渲染速度更快,只有点击懒加载路由的时候,对应的模块才会更改。

const routes: Routes = [     {         path: 'load',         loadChildren: () => import('./load/load.module').then(m => m.ListModule),         // CanLoadModule如果返回false,模块里面的子路由都没有办法访问         canLoad: [CanLoadModule]     }, ]

懒加载模块路由配置:

import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LoadComponent } from './Load.component'; import { RouterModule, Routes } from '@angular/router'; import { LoadTwoComponent } from '../../../app/components/LoadTwo/LoadTwo.component'; import { LoadOneComponent } from '../../../app/components/LoadOne/LoadOne.component';  const routes: Routes = [     {         path: "",         component: LoadComponent,         children: [             { path: "LoadOne", component: LoadOneComponent },             { path: "LoadTwo", component: LoadTwoComponent }         ]     },  ]  @NgModule({     imports: [         CommonModule,         //子模块使用forChild配置         RouterModule.forChild(routes)     ],      declarations: [         LoadComponent,         LoadOneComponent,         LoadTwoComponent     ] }) export class LoadModule { }

懒加载模块路由导航:

<a [routerLink]="[ 'LoadOne' ]">LoadOne</a> <a [routerLink]="[ 'LoadTwo' ]">LoadTwo</a> <router-outlet></router-outlet>

路由参数传递:

const routes: Routes = [     { path: "second/:id", component: SecondComponent }, ]
//routerLinkActive配置路由激活时的类 <a [routerLink]="[ '/second', 12 ]" routerLinkActive="active">second</a>

获取路由传递的参数:

import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { Component, OnInit } from '@angular/core'; import { switchMap } from 'rxjs/operators';  @Component({     selector: 'app-second',     templateUrl: './second.component.html',     styleUrls: ['./second.component.scss'] }) export class SecondComponent implements OnInit {      constructor(private activatedRoute: ActivatedRoute, private router: Router) { }      ngOnInit() {          console.log(this.activatedRoute.snapshot.params);  //{id: "12"}         // console.log(this.activatedRoute);         // 这种形式可以捕获到url输入 /second/18 然后点击<a [routerLink]="[ '/second', 12 ]">second</a>            // 是可以捕获到的。上面那种是捕获不到的。因为不会触发ngOnInit,公用了一个组件实例。         this.activatedRoute.paramMap.pipe(             switchMap((params: ParamMap) => {                 console.log(params.get('id'));                 return "param";         })).subscribe(() => {          })     }     gotoFirst() {         this.router.navigate(["/first"]);     }  }

queryParams参数传值,参数获取也是通过激活的路由的依赖注入

<!-- queryParams参数传值 --> <a [routerLink]="[ '/first' ]" [queryParams]="{name: 'first'}">first</a>    <!-- ts中传值 --> <!-- this.router.navigate(['/first'],{ queryParams: { name: 'first' }); -->

路由守卫:canActivate,canDeactivate,resolve,canLoad

路由守卫会返回一个值,如果返回true继续执行,false阻止该行为,UrlTree导航到新的路由。 路由守卫可能会导航到其他的路由,这时候应该返回false。路由守卫可能会根据服务器的值来 决定是否进行导航,所以还可以返回Promise或 Observable,路由会等待 返回的值是true还是false。 canActivate导航到某路由。 canActivateChild导航到某子路由。

const routes: Routes = [     {         path: "parent",         component: ParentComponent,         canActivate: [AuthGuard],         children: [             // 无组件子路由             {                 path: "",                 canActivateChild: [AuthGuardChild],                 children: [                     { path: "childOne", component: ChildOneComponent },                     { path: "childTwo", component: ChildTwoComponent }                 ]             }         ],         // 有组件子路由         // children: [         //     { path: "childOne", component: ChildOneComponent },         //     { path: "childTwo", component: ChildTwoComponent }         // ]     } ]
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';  @Injectable({   providedIn: 'root', }) export class AuthGuard implements CanActivate {   canActivate(     next: ActivatedRouteSnapshot,     state: RouterStateSnapshot): any {     // return true;     // 返回Promise的情况     return new Promise((resolve,reject) => {         setTimeout(() => {             resolve(true);         }, 3000);     })   } }
import { Injectable } from '@angular/core'; import {   ActivatedRouteSnapshot,   RouterStateSnapshot,   CanActivateChild } from '@angular/router';  @Injectable({   providedIn: 'root', }) export class AuthGuardChild implements CanActivateChild {   constructor() {}     canActivateChild(     route: ActivatedRouteSnapshot,     state: RouterStateSnapshot): boolean {     return true;   } }

parent.component.html路由导航:

<!-- 使用相对路径 --> <a [routerLink]="[ './childOne' ]">one</a> <!-- 使用绝对路径 --> <a [routerLink]="[ '/parent/childTwo' ]">two</a> <router-outlet></router-outlet>

canDeactivate路由离开,提示用户没有保存信息的情况。

const routes: Routes = [     { path: "first", component: FirstComponent, canDeactivate: [CanDeactivateGuard] } ]
import { FirstComponent } from './components/first/first.component'; import { RouterStateSnapshot } from '@angular/router'; import { ActivatedRouteSnapshot } from '@angular/router'; import { Injectable } from '@angular/core'; import { CanDeactivate } from '@angular/router';  @Injectable({     providedIn: 'root', }) export class CanDeactivateGuard implements CanDeactivate<any> {     canDeactivate(         component: any,         route: ActivatedRouteSnapshot,         state: RouterStateSnapshot     ): boolean {         // component获取到组件实例         console.log(component.isLogin);         return true;     } }

canLoad是否能进入懒加载模块:

const routes: Routes = [     {         path: 'load',         loadChildren: () => import('./load/load.module').then(m => m.LoadModule),         // CanLoadModule如果返回false,模块里面的子路由都没有办法访问         canLoad: [CanLoadModule]     } ]
import { Route } from '@angular/compiler/src/core'; import { Injectable } from '@angular/core'; import { CanLoad } from '@angular/router';   @Injectable({     providedIn: 'root', }) export class CanLoadModule implements CanLoad {     canLoad(route: Route): boolean {          return true;       } }

resolve配置多久后可以进入路由,可以在进入路由前获取数据,避免白屏

const routes: Routes = [     { path: "resolve", component: ResolveDemoComponent, resolve: {detail: DetailResolver}  ]
import { Injectable } from '@angular/core'; import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';  @Injectable({ providedIn: 'root' }) export class DetailResolver implements Resolve<any> {    constructor() { }    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {     return new Promise((resolve,reject) => {         setTimeout(() => {             resolve("resolve data");         }, 3000);     })   } }

ResolveDemoComponent获取resolve的值

constructor(private route: ActivatedRoute) { } ngOnInit() {     const detail = this.route.snapshot.data.detail;     console.log(detail); }

监听路由事件:

constructor(private router: Router) {     this.router.events.subscribe((event) => {         // NavigationEnd,NavigationCancel,NavigationError,RoutesRecognized         if (event instanceof NavigationStart) {             console.log("NavigationStart");         }     }) }

赞(0)
分享到: 更多 (0)