Angular 從入坑到挖坑 - Router 路由使用入門指北

来源:https://www.cnblogs.com/danvic712/archive/2020/05/11/getting-started-with-angular-routing.html
-Advertisement-
Play Games

一、Overview Angular 入坑記錄的筆記第五篇,因為一直在加班的緣故拖了有一個多月,主要是介紹在 Angular 中如何配置路由,完成重定向以及參數傳遞。至於路由守衛、路由懶載入等“高級”特性,並不會在本篇文章中呈現 對應官方文檔地址: "路由與導航" 配套代碼地址: "angular ...


一、Overview

Angular 入坑記錄的筆記第五篇,因為一直在加班的緣故拖了有一個多月,主要是介紹在 Angular 中如何配置路由,完成重定向以及參數傳遞。至於路由守衛、路由懶載入等“高級”特性,並不會在本篇文章中呈現

對應官方文檔地址:

配套代碼地址:angular-practice/src/router-tutorial

二、Contents

  1. Angular 從入坑到棄坑 - Angular 使用入門
  2. Angular 從入坑到挖坑 - 組件食用指南
  3. Angular 從入坑到挖坑 - 表單控制項概覽
  4. Angular 從入坑到挖坑 - HTTP 請求概覽
  5. Angular 從入坑到挖坑 - Router 路由使用入門指北

三、Knowledge Graph

思維導圖

四、Step by Step

4.1、基礎概念

4.1.1、base url

在 Angular 應用中,框架會自動將 index.html 文件中的 base url 配置作為組件、模板和模塊文件的基礎路徑地址。預設的情況下 app 文件夾是整個應用的根目錄,所以我們直接使用 index.html 中使用預設的 <base href='/'> 即可

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>RouterTutorial</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>
4.1.2、路由的配置

在 Angular 項目中,系統的路由需要我們將一個 url 地址映射到一個展示的組件,因此需要手動的去設置 url 與組件之間的映射關係

因為我們在使用 Angular CLI 創建項目時,選擇了添加路由模組,因此我們可以直接在 app-routing.module.ts 文件中完成路由的定義。最終我們定義的路由信息,都會在根模塊中被引入到整個項目

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './components/home/home.component';
import { PagenotfoundComponent } from './components/pagenotfound/pagenotfound.component';
import { NewsComponent } from './components/news/news.component';
import { ProductComponent } from './components/product/product.component';

// 配置路由信息
const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'news', component: NewsComponent },
  { path: 'product', component: ProductComponent },
  { path: '**', component: PagenotfoundComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule // 引入路由配置信息
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

路由配置

當定義好路由信息後,我們需要在頁面上使用 <router-outlet> 標簽來告訴 Angular 在何處渲染出頁面。對於路由之間的跳轉,我們可以在 a 標簽上通過使用 RouterLink 指令來綁定具體的路由來完成地址的跳轉

<div class="card-container">
    <a class="card" [routerLink]="[ '/news' ]" routerLinkActive="active">
      <span>News</span>
    </a>
    <a class="card" [routerLink]="[ '/product' ]" routerLinkActive="active">
      <span>Product</span>
    </a>

  </div>

  <div class="card-container">
    <div class="form-card">
      <!-- 組件渲染的出口 -->
      <router-outlet></router-outlet>
    </div>
  </div>
</div>

當然,如果你非要自己給自己找事,就是要用 a 標簽的 href 屬性進行跳轉,當然也是可以的,不過在後面涉及到相關框架的功能時就會顯得有點不辣麽聰明的樣子了

4.1.3、重定向與通配地址

在普遍情況下,對於進入系統後的預設路徑,我們會選擇重定向到一個具體的地址上,這裡我們在定義路由信息時,定義了一個空路徑用來表示系統的預設地址,當用戶請求時,重定向到 /home 路徑上,因為只有完整的 url 地址匹配空字元串時才應該進行重定向操作,所以這裡需要指定匹配模式是全部匹配

預設地址重定向

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];

Angular 在解析路由時,是按照我們定義路由時的順序依次進行的,一旦匹配就會立即終止。因此,類似於 404 錯誤的這種通配的路由配置,因為可以匹配上每個 url 地址,所以應該在定義時放到最後

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'news', component: NewsComponent },
  { path: 'product', component: ProductComponent },
  { path: '**', component: PagenotfoundComponent },
];

路由示例

從截圖中可以看到,當我們打開系統時,會自動跳轉到我們指定的 home 路徑,點擊菜單按鈕後,則會載入對應的組件頁面

4.1.4、激活的路由

很多情況下,對於被選中的路由,我們可能會添加一個特定的樣式來進行提示用戶,因此,在我們定義 router-link 時,可以使用 routerLinkActive 屬性綁定一個 css 的樣式類,當該鏈接對應的路由處於激活狀態時,則自動添加上指定的樣式類

激活狀態的路由

4.2、路由間的參數傳遞

在進行路由跳轉時,很常見的一種使用情況是我們需要將某些數據作為參數傳遞到下一個頁面中,例如從列表中選擇點擊某一行數據,跳轉到對應的詳情頁面

常見的參數傳遞有如下的兩種方式

4.2.1、query 查詢參數傳遞

最常見的一種參數傳遞的方式,在需要跳轉的路由地址後面加上參數和對應的值,在跳轉後的頁面通過獲取參數 key 從而獲取到對應的參數值

<a href="www.yoursite.com/product?productId=xxxx">跳轉</a>

對於直接通過 a 標簽進行的路由跳轉,我們可以在 a 標簽上通過綁定 queryParams 屬性來添加查詢參數信息

這裡通過 queryParams 屬性綁定的是一個對象,Angular 會自動的幫我們將這個參數對象與 url 進行拼接。對於參數對象中的屬性(key)對應的屬性值(value),我們可以綁定一個組件中的屬性進行動態的賦值,也可以通過添加單引號將參數值作為一個固定的數值,例如在下麵代碼中的兩個查詢參數就是固定的值

<a class="card" [routerLink]="[ '/news' ]" routerLinkActive="active" [queryParams]="{category:'social',date:'2020-05-02'}">News</a>

query 參數傳值

同樣的,我們也可以在 js 中完成路由的跳轉,對於這種使用場景,我們需要在進行 js 跳轉的組件類中通過構造函數依賴註入 Router 類,之後通過 Router 類的 navigate 方法完成路由的跳轉;對於可能存在的查詢參數,我們需要定義一個 NavigationExtras 類型的變數來進行設置

import { Component, OnInit } from '@angular/core';

// 引入路由模塊
import { Router, NavigationExtras } from '@angular/router';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  constructor(private router: Router) {}

  ngOnInit(): void {}

  /**
   * 使用 js 的方式通過 query 查詢字元串的形式傳遞參數
   */
  queryNavigate() {

    // 查詢參數
    let query: NavigationExtras = {
      queryParams: {
        category: 'social',
        date: '2020-05-04'
      }
    };
    this.router.navigate(['/news' ], query);
  }
}

既然在進行跳轉時附加了參數信息,在跳轉後的頁面我們肯定需要獲取到傳遞的參數值。在 Angular 中,需要在組件類中依賴註入 ActivatedRoute 來獲取傳遞的參數信息

這裡的 queryParamMap 是一個 Observable 對象,所以這裡需要使用 subscribe 方法來獲取傳遞的參數值

import { Component, OnInit } from '@angular/core';

// 引入路由模塊
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.scss']
})
export class NewsComponent implements OnInit {

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {

    this.route.queryParamMap.subscribe((data: any) => {
      console.log(data.params);
    });
  }

}

獲取 query 查詢參數傳遞的參數值

4.2.2、動態路由傳遞

與使用查詢參數不同,使用動態路由進行參數傳值時,需要我們在定義路由時就提供參數的占位符信息,例如在下麵定義路由的代碼里,對於組件所需的參數 newsId,我們需要在定義路由時就指明

const routes: Routes = [
  { path: 'news/detail/:newsId', component: NewsDetailComponent },
];

對於採用動態路由進行的路由跳轉,在 a 標簽綁定的 routerLink 屬性數組的第二個數據中,需要指定我們傳遞的參數值。例如這裡的 item.newsId 變數就是我們需要傳遞的參數值

<ul>
  <li *ngFor="let item of newsList; let i = index">
    <a [routerLink]="['/news/detail', item.newsId]" routerLinkActive="active" >
      {{item.title}}
    </a>
  </li>
</ul>

而採用 js 的方式進行跳轉時,我們同樣需要使用依賴註入的方式註入 Router 類,然後調用 navigate 方法進行跳轉。與使用 query 查詢參數傳遞數據不同,此時需要將跳轉的鏈接與對應的參數值組合成為一個數組參數進行傳遞

import { Component, OnInit } from '@angular/core';

// 引入路由模塊
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.scss']
})
export class NewsComponent implements OnInit {

  newsList: any;

  constructor(private route: ActivatedRoute, private router: Router) {
    this.newsList = [{
      newsId: 1111,
      title: 'lalalalalallaaa'
    }, {
      newsId: 2222,
      title: 'lalalalalallaaa'
    }, {
      newsId: 3333,
      title: 'lalalalalallaaa'
    }];

  }

  ngOnInit(): void {
    this.route.queryParamMap.subscribe((data: any) => {
      console.log(data.params);
    });
  }

  routerNavigate() {
    this.router.navigate(['/news/detail', 11111]);
  }
}

在獲取參數數據的組件類中,需要依賴註入 ActivatedRoute 類,因為是採用的動態路由的方式進行的參數傳遞,這裡需要通過 paramMap 屬性獲取到對應的參數值

import { Component, OnInit } from '@angular/core';

// 引入路由模塊
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-news-detail',
  templateUrl: './news-detail.component.html',
  styleUrls: ['./news-detail.component.scss']
})
export class NewsDetailComponent implements OnInit {

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {
    this.route.paramMap.subscribe((data: any) => {
      console.log(data.params);
    });
  }
}

獲取動態路由傳遞的參數值

4.3、嵌套路由

在一些情況下,路由是存在嵌套關係的,例如下麵這個頁面,只有當我們點擊資源這個頂部的菜單後,它才會顯示出左側的這些菜單,也就是說這個頁面左側的菜單的父級菜單是頂部的資源菜單

嵌套路由

針對這種具有嵌套關係的路由,在定義路由時,我們需要通過配置 children 屬性來指定路由之間的嵌套關係,例如這裡我定義 ProductDetailComponent 這個組件和 ProductComponent 組件形成的路由之間具有嵌套關係

// 配置路由信息
const routes: Routes = [
  {
    path: 'product', component: ProductComponent, children: [{
      path: 'detail', component: ProductDetailComponent
    }, {
      path: '', redirectTo: 'detail', pathMatch: 'full'
    }]
  }
];

因為子路由的渲染出口是在父路由的頁面上,因此當嵌套路由配置完成之後,在嵌套的父級頁面上,我們需要定義一個 <router-outlet> 標簽用來指定子路由的渲染出口,最終的效果如下圖所示

<h3>我是父路由頁面顯示的內容</h3>
<p>product works!</p>

<!-- 載入子路由的數據 -->
<h3>子路由組件渲染的出口</h3>
<router-outlet></router-outlet>

嵌套路由


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 《Vue.js 2.x實踐指南》其實早在一年前就已經完稿,只是由於疫情的緣故耽擱了許久才下廠印刷。 本書旨在讓初學者能夠快速上手vue技術棧,並能夠利用所學知識獨立動手進行項目開發。我的寫作風格一向都是喜歡採用理論和實踐相結合的方式,這樣學習起來不會那麼枯燥,而且極具成效。時間是很寶貴的東西,所以盡 ...
  • 可視化編(rxeditor)輯告一段落,在知乎上發了一個問題,詢問前景,雖然看好的不多,但是關註度還是有的,目前為止積累了21w流量,因為這個事,開心了好長一段時間。這一個月的時間,主要在設計製作Vular,基於Vuetify跟larval實現的,可拼插式應用框架。並且把RXEditor可視化編輯也 ...
  • spring boot 使用 Thymeleaf +layui 使用到的功能實例 ...
  • 內容概述 本系列“vue項目中使用bpmn-xxxx”分為七篇,均為自己使用過程中用到的實例,手工原創,目前陸續更新中。主要包括vue項目中bpmn使用實例、應用技巧、基本知識點總結和需要註意事項,具有一定的參考價值,需要的朋友可以參考一下。如果轉載或通過爬蟲直接爬的,格式特別醜,請來原創看:我是作 ...
  • 最近和做技術的朋友聊天的時候,發現自己居然不能將函數式編程思想講清楚,於是做一次複習 一、函數是“一等公民” 常常都能聽到這麼一句話:在 JavaScript 中,函數是“一等公民”,這句話到底意味著什麼? 在編程語言中,一等公民可以作為函數參數,可以作為函數返回值,也可以賦值給變數 —— Chri ...
  • 瞭解HTML5 新語義標簽 "http://www.w3school.com.cn/html/html5_semantic_elements.asp" 語義標簽相容性處理 解決方案一:通過創建元素的方式,然後將元素轉化為塊級元素即可 解決方案二:通過引用第三方js插件方式(本質也是用createEl ...
  • # jQuery事件 - 1.on() ```js //1.事件類型type 2.selector 3.data 4.handle $('ul').on('click', 'li', function(e){ alert($(e.target).text()); });//點擊ul下的li元素觸發h ...
  • 下載 進入node.js官網的下載頁面 "node.js下載頁面" ,選擇合適的版本進行下載 配置 1.設置環境變數 隨便找一個地方,將文件解壓出來 複製當前的路徑,我的電腦右鍵,打開屬性,左邊有個高級系統配置,之後再打開環境變數 選擇Path選項,點開編輯,把之前複製的路徑粘貼即可 之後在命令行輸 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...