千家信息网

如何理解Angular中的路由

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章将为大家详细讲解有关如何理解Angular中的路由,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。!在 Angular 中,路由是以模块为单位的
千家信息网最后更新 2025年01月19日如何理解Angular中的路由

这篇文章将为大家详细讲解有关如何理解Angular中的路由,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Angular 中,路由是以模块为单位的,每个模块都可以有自己的路由。

快速上手

创建页面组件、Layout 组件以及 Navigation 组件,供路由使用

  • 创建首页页面组件ng g c pages/home

  • 创建关于我们页面组件ng g c pages/about

  • 创建布局组件ng g c pages/layout

  • 创建导航组件ng g c pages/navigation

创建路由规则

// app.module.tsimport { Routes } from "@angular/router"const routes: Routes = [  {    path: "home",    component: HomeComponent  },  {    path: "about",    component: AboutComponent  }]

引入路由模块并启动

// app.module.tsimport { RouterModule, Routes } from "@angular/router"@NgModule({  imports: [RouterModule.forRoot(routes, { useHash: true })],})export class AppModule {}

添加路由插座

在导航组件中定义链接

首页关于我们

匹配规则

1、重定向

const routes: Routes = [  {    path: "home",    component: HomeComponent  },  {    path: "about",    component: AboutComponent  },  {    path: "",    // 重定向    redirectTo: "home",    // 完全匹配    pathMatch: "full"  }]

2、404 页面

const routes: Routes = [  {    path: "home",    component: HomeComponent  },  {    path: "**",    component: NotFoundComponent  }]

路由传参

1、查询参数

关于我们
import { ActivatedRoute } from "@angular/router"export class AboutComponent implements OnInit {  constructor(private route: ActivatedRoute) {}  ngOnInit(): void {    this.route.queryParamMap.subscribe(query => {      query.get("name")    })  }}

2、动态参数

const routes: Routes = [  {    path: "home",    component: HomeComponent  },  {    path: "about/:name",    component: AboutComponent  }]
关于我们
import { ActivatedRoute } from "@angular/router"export class AboutComponent implements OnInit {  constructor(private route: ActivatedRoute) {}  ngOnInit(): void {    this.route.paramMap.subscribe(params => {      params.get("name")    })  }}

路由嵌套

路由嵌套指的是如何定义子级路由

const routes: Routes = [  {    path: "about",    component: AboutComponent,    children: [      {        path: "introduce",        component: IntroduceComponent      },      {        path: "history",        component: HistoryComponent      }    ]  }]
  

about works!

公司简介 发展历史

命名插座

将子级路由组件显示到不同的路由插座中

{  path: "about",  component: AboutComponent,  children: [    {      path: "introduce",      component: IntroduceComponent,      outlet: "left"    },    {      path: "history",      component: HistoryComponent,      outlet: "right"    }  ]}
  

about works!

关于我们

导航路由

// app.component.tsimport { Router } from "@angular/router"export class HomeComponent {  constructor(private router: Router) {}  jump() {    this.router.navigate(["/about/history"], {      queryParams: {        name: "Kitty"      }    })  }}

路由模块

将根模块中的路由配置抽象成一个单独的路由模块,称之为根路由模块,然后在根模块中引入根路由模块

import { NgModule } from "@angular/core"import { HomeComponent } from "./pages/home/home.component"import { NotFoundComponent } from "./pages/not-found/not-found.component"const routes: Routes = [  {    path: "",    component: HomeComponent  },  {    path: "**",    component: NotFoundComponent  }]@NgModule({  declarations: [],  imports: [RouterModule.forRoot(routes, { useHash: true })],  // 导出 Angular 路由功能模块,因为在根模块的根组件中使用了 RouterModule 模块中提供的路由插座组件  exports: [RouterModule]})export class AppRoutingModule {}
import { BrowserModule } from "@angular/platform-browser"import { NgModule } from "@angular/core"import { AppComponent } from "./app.component"import { AppRoutingModule } from "./app-routing.module"@NgModule({  declarations: [AppComponent],  imports: [BrowserModule, AppRoutingModule],  providers: [],  bootstrap: [AppComponent]})export class AppModule {}

路由懒加载

路由懒加载是以模块为单位的。

  • 创建用户模块 ng g m user --routing=true 并创建该模块的路由模块

  • 创建登录页面组件 ng g c user/pages/login

  • 创建注册页面组件 ng g c user/pages/register

  • 配置用户模块的路由规则

import { NgModule } from "@angular/core"import { Routes, RouterModule } from "@angular/router"import { LoginComponent } from "./pages/login/login.component"import { RegisterComponent } from "./pages/register/register.component"const routes: Routes = [  {    path: "login",    component: LoginComponent  },  {    path: "register",    component: RegisterComponent  }]@NgModule({  imports: [RouterModule.forChild(routes)],  exports: [RouterModule]})export class UserRoutingModule {}
  • 将用户路由模块关联到主路由模块

    // app-routing.module.tsconst routes: Routes = [  {    path: "user",    loadChildren: () => import("./user/user.module").then(m => m.UserModule)  }]
  • 在导航组件中添加访问链接

    登录注册

路由守卫

路由守卫会告诉路由是否允许导航到请求的路由。

路由守方法可以返回 booleanObservable \Promise \,它们在将来的某个时间点解析为布尔值

1、CanActivate

检查用户是否可以访问某一个路由。

CanActivate 为接口,路由守卫类要实现该接口,该接口规定类中需要有 canActivate 方法,方法决定是否允许访问目标路由。

路由可以应用多个守卫,所有守卫方法都允许,路由才被允许访问,有一个守卫方法不允许,则路由不允许被访问。

创建路由守卫:ng g guard guards/auth

import { Injectable } from "@angular/core"import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from "@angular/router"import { Observable } from "rxjs"@Injectable({  providedIn: "root"})export class AuthGuard implements CanActivate {  constructor(private router: Router) {}  canActivate(): boolean | UrlTree {    // 用于实现跳转    return this.router.createUrlTree(["/user/login"])    // 禁止访问目标路由    return false    // 允许访问目标路由    return true  }}
{  path: "about",  component: AboutComponent,  canActivate: [AuthGuard]}

2、CanActivateChild

检查用户是否方可访问某个子路由。

创建路由守卫:ng g guard guards/admin

注意:选择 CanActivateChild,需要将箭头移动到这个选项并且敲击空格确认选择

import { Injectable } from "@angular/core"import { CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from "@angular/router"import { Observable } from "rxjs"@Injectable({  providedIn: "root"})export class AdminGuard implements CanActivateChild {  canActivateChild(): boolean | UrlTree {    return true  }}
{  path: "about",  component: AboutComponent,  canActivateChild: [AdminGuard],  children: [    {      path: "introduce",      component: IntroduceComponent    }  ]}

3、CanDeactivate

检查用户是否可以退出路由。比如用户在表单中输入的内容没有保存,用户又要离开路由,此时可以调用该守卫提示用户

import { Injectable } from "@angular/core"import {  CanDeactivate,  ActivatedRouteSnapshot,  RouterStateSnapshot,  UrlTree} from "@angular/router"import { Observable } from "rxjs"export interface CanComponentLeave {  canLeave: () => boolean}@Injectable({  providedIn: "root"})export class UnsaveGuard implements CanDeactivate {  canDeactivate(component: CanComponentLeave): boolean {    if (component.canLeave()) {      return true    }    return false  }}
{  path: "",  component: HomeComponent,  canDeactivate: [UnsaveGuard]}
import { CanComponentLeave } from "src/app/guards/unsave.guard"export class HomeComponent implements CanComponentLeave {  myForm: FormGroup = new FormGroup({    username: new FormControl()  })  canLeave(): boolean {    if (this.myForm.dirty) {      if (window.confirm("有数据未保存, 确定要离开吗")) {        return true      } else {        return false      }    }    return true  }

4、Resolve

允许在进入路由之前先获取数据,待数据获取完成之后再进入路由

$ ng g resolver 
import { Injectable } from "@angular/core"import { Resolve } from "@angular/router"type returnType = Promise<{ name: string }>@Injectable({  providedIn: "root"})export class ResolveGuard implements Resolve {  resolve(): returnType {    return new Promise(function (resolve) {      setTimeout(() => {        resolve({ name: "张三" })      }, 2000)    })  }}
{   path: "",   component: HomeComponent,   resolve: {     user: ResolveGuard   }}
export class HomeComponent {  constructor(private route: ActivatedRoute) {}  ngOnInit(): void {    console.log(this.route.snapshot.data.user)  }}

关于如何理解Angular中的路由就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0