溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么

發(fā)布時(shí)間:2021-06-25 12:06:30 來(lái)源:億速云 閱讀:218 作者:chen 欄目:web開(kāi)發(fā)

這篇文章主要介紹“Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么”,在日常操作中,相信很多人在Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

Installing the router

首先第一件事,我們需要安裝 Angular Router。你可以通過(guò)運(yùn)行以下任一操作來(lái)執(zhí)行此操作:

yarn add @angular/router
# OR
npm i --save @angular/router

以上命令執(zhí)行后,將會(huì)自動(dòng)下載 @angular/router 模塊到 node_modules 文件夾中。

Base href

我們需要做的最后一件事,是將 <base> 標(biāo)簽添加到我們的 index.html 文件中。路由需要根據(jù)這個(gè)來(lái)確定應(yīng)用程序的根目錄。例如,當(dāng)我們轉(zhuǎn)到 http://example.com/page1 時(shí),如果我們沒(méi)有定義應(yīng)用程序的基礎(chǔ)路徑,路由將無(wú)法知道我們的應(yīng)用的托管地址是 http://example.com 還是 http://example.com/page1

這件事操作起來(lái)很簡(jiǎn)單,只需打開(kāi)項(xiàng)目中的 index.html 文件,添加相應(yīng)的 <base> 標(biāo)簽,具體如下:

<!doctype html>
<html>
  <head>
    <base href="/">
    <title>Application</title>
  </head>
  <body>
    <app-root></app-root>
  </body>
</html>

以上配置信息告訴 Angular 路由,應(yīng)用程序的根目錄是 / 。

Using the router

要使用路由,我們需要在 AppModule 模塊中,導(dǎo)入 RouterModule。具體如下:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    RouterModule
  ],
  bootstrap: [
    AppComponent
  ],
  declarations: [
    AppComponent
  ]
})
export class AppModule {}

此時(shí)我們的路由還不能正常工作,因?yàn)槲覀冞€未配置應(yīng)用程序路由的相關(guān)信息。RouterModule 對(duì)象為我們提供了兩個(gè)靜態(tài)的方法:forRoot()forChild() 來(lái)配置路由信息。

RouterModule.forRoot()

RouterModule.forRoot() 方法用于在主模塊中定義主要的路由信息,通過(guò)調(diào)用該方法使得我們的主模塊可以訪問(wèn)路由模塊中定義的所有指令。接下來(lái)我們來(lái)看一下如何使用 forRoot()

// ...
import { Routes, RouterModule } from '@angular/router';

export const ROUTES: Routes = [];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
  // ...
})
export class AppModule {}

我們通過(guò)使用 const 定義路由的配置信息,然后把它作為參數(shù)調(diào)用 RouterModule.forRoot() 方法,而不是直接使用 RouterModule.forRoot([...]) 這種方式,這樣做的好處是方便我們?cè)谛枰臅r(shí)候?qū)С?ROUTES 到其它模塊中。

RouterModule.forChild()

RouterModule.forChild()Router.forRoot() 方法類似,但它只能應(yīng)用在特性模塊中。
友情提示:根模塊中使用 forRoot(),子模塊中使用 forChild()
這個(gè)功能非常強(qiáng)大,因?yàn)槲覀儾槐卦谝粋€(gè)地方(我們的主模塊)定義所有路由信息。反之,我們可以在特性模塊中定義模塊特有的路由信息,并在必要的時(shí)候?qū)⑺鼈儗?dǎo)入我們主模塊。RouterModule.forChild() 的使用方法如下:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

export const ROUTES: Routes = [];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(ROUTES)
  ],
  // ...
})
export class ChildModule {}

通過(guò)以上示例,我們知道在主模塊和特性模塊中,路由配置對(duì)象的類型是一樣的,區(qū)別只是主模塊和特性模塊中需調(diào)用不同的方法,來(lái)配置模塊路由。接下來(lái)我們來(lái)介紹一下如何配置 ROUTES 對(duì)象。

Configuring a route

我們定義的所有路由都是作為 ROUTES 數(shù)組中的對(duì)象。首先,為我們的主頁(yè)定義一個(gè)路由:

import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home/home.component';

export const ROUTES: Routes = [
  { path: '', component: HomeComponent }
];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
  // ...
})
export class AppModule {}

示例中我們通過(guò) path 屬性定義路由的匹配路徑,而 component 屬性用于定義路由匹配時(shí)需要加載的組件。

友情提示:我們使用 path: '' 來(lái)匹配空的路徑,例如:https://yourdomain.com

Displaying routes

配置完路由信息后,下一步是使用一個(gè)名為 router-outlet 的指令告訴 Angular 在哪里加載組件。當(dāng) Angular 路由匹配到響應(yīng)路徑,并成功找到需要加載的組件時(shí),它將動(dòng)態(tài)創(chuàng)建對(duì)應(yīng)的組件,并將其作為兄弟元素,插入到 router-outlet 元素中。

在我們 AppComponent 組件中,我們可以在任意位置插入 router-outlet指令:

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

@Component({
  selector: 'app-root',
  template: `
    <div class="app">
      <h4>Our app</h4>
      <router-outlet></router-outlet>
    </div>
  `
})
export class AppComponent {}

我們現(xiàn)在已經(jīng)建立了應(yīng)用程序的主路由,我們可以進(jìn)一步了解路由的其它配置選項(xiàng)。

Further configuration

到目前為止我們已經(jīng)介紹的內(nèi)容只是一個(gè)開(kāi)始 ,接下來(lái)我們來(lái)看看其它一些選項(xiàng)和功能。

Dynamic routes

如果路由始終是靜態(tài)的,那沒(méi)有多大的用處。例如 path: '' 是加載我們 HomeComponent 組件的靜態(tài)路由。我們將介紹動(dòng)態(tài)路由,基于動(dòng)態(tài)路由我們可以根據(jù)不同的路由參數(shù),渲染不同的頁(yè)面。

例如,如果我們想要在個(gè)人資料頁(yè)面根據(jù)不同的用戶名顯示不同的用戶信息,我們可以使用以下方式定義路由:

import { HomeComponent } from './home/home.component';
import { ProfileComponent } from './profile/profile.component';

export const ROUTES: Routes = [
  { path: '', component: HomeComponent },
  { path: '/profile/:username', component: ProfileComponent }
];

這里的關(guān)鍵點(diǎn)是 : ,它告訴 Angular 路由,:username 是路由參數(shù),而不是 URL 中實(shí)際的部分。

友情提示:如果沒(méi)有使用 : ,它將作為靜態(tài)路由,僅匹配 /profile/username 路徑
現(xiàn)在我們已經(jīng)建立一個(gè)動(dòng)態(tài)路由,此時(shí)最重要的事情就是如何獲取路由參數(shù)。要訪問(wèn)當(dāng)前路由的相關(guān)信息,我們需要先從 @angular/router 模塊中導(dǎo)入 ActivatedRoute ,然后在組件類的構(gòu)造函數(shù)中注入該對(duì)象,最后通過(guò)訂閱該對(duì)象的 params 屬性,來(lái)獲取路由參數(shù),具體示例如下:

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

@Component({
  selector: 'profile-page',
  template: `
    <div class="profile">
      <h4>{{ username }}</h4>
    </div>
  `
})
export class SettingsComponent implements OnInit {
  username: string;
  constructor(private route: ActivatedRoute) {}
  ngOnInit() {
    this.route.params.subscribe((params) => this.username = params.username);
  }
}

介紹完動(dòng)態(tài)路由,我們來(lái)探討一下如何創(chuàng)建 child routes。

Child routes

實(shí)際上每個(gè)路由都支持子路由,假設(shè)在我們 /settings 設(shè)置頁(yè)面下有 /settings/profile/settings/password 兩個(gè)頁(yè)面,分別表示個(gè)人資料頁(yè)和修改密碼頁(yè)。

我們可能希望我們的 /settings 頁(yè)面擁有自己的組件,然后在設(shè)置頁(yè)面組件中顯示 /settings/profile/settings/password 頁(yè)面。我們可以這樣做:

import { SettingsComponent } from './settings/settings.component';
import { ProfileSettingsComponent } from './settings/profile/profile.component';
import { PasswordSettingsComponent } from './settings/password/password.component';

export const ROUTES: Routes = [
  { 
    path: 'settings', 
    component: SettingsComponent,
    children: [
      { path: 'profile', component: ProfileSettingsComponent },
      { path: 'password', component: PasswordSettingsComponent }
    ]
  }
];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
})
export class AppModule {}

在這里,我們?cè)?setttings 路由中定義了兩個(gè)子路由,它們將繼承父路由的路徑,因此修改密碼頁(yè)面的路由匹配地址是 /settings/password ,依此類推。

接下來(lái),我們需要做的最后一件事是在我們的 SettingsComponent 組件中添加 router-outlet 指令,因?yàn)槲覀円谠O(shè)置頁(yè)面中呈現(xiàn)子路由。如果我們沒(méi)有在 SettingsComponent 組件中添加 router-outlet 指令,盡管 /settings/password 匹配修改密碼頁(yè)面的路由地址,但修改密碼頁(yè)面將無(wú)法正常顯示。具體代碼如下:

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

@Component({
  selector: 'settings-page',
  template: `
    <div class="settings">
      <settings-header></settings-header>
      <settings-sidebar></settings-sidebar>
      <router-outlet></router-outlet>
    </div>
  `
})
export class SettingsComponent {}
Component-less routes

另一個(gè)很有用的路由功能是 component-less 路由。使用 component-less 路由允許我們將路由組合在一起,并讓它們共享路由配置信息和 outlet。

例如,我們可以定義 setttings 路由而不需要使用 SettingsComponent 組件:

import { ProfileSettingsComponent } from './settings/profile/profile.component';
import { PasswordSettingsComponent } from './settings/password/password.component';

export const ROUTES: Routes = [
  {
    path: 'settings',
    children: [
      { path: 'profile', component: ProfileSettingsComponent },
      { path: 'password', component: PasswordSettingsComponent }
    ]
  }
];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
})
export class AppModule {}

此時(shí), /settings/profile/settings/password 路由定義的內(nèi)容,將顯示在 AppComponent 組件的 router-outlet 元素中。

loadChildren

我們也可以告訴路由從另一個(gè)模塊中獲取子路由。這將我們談?wù)摰膬蓚€(gè)想法聯(lián)系在一起 - 我們可以指定另一個(gè)模塊中定義的子路由,以及通過(guò)將這些子路由設(shè)置到特定的路徑下,來(lái)充分利用 component-less 路由的功能。

讓我們創(chuàng)建一個(gè) SettingsModule 模塊,用來(lái)保存所有 setttings 相關(guān)的路由信息:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

export const ROUTES: Routes = [
  {
    path: '',
    component: SettingsComponent,
    children: [
      { path: 'profile', component: ProfileSettingsComponent },
      { path: 'password', component: PasswordSettingsComponent }
    ]
  }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(ROUTES)
  ],
})
export class SettingsModule {}

需要注意的是,在 SettingsModule 模塊中我們使用 forChild() 方法,因?yàn)?SettingsModule 不是我們應(yīng)用的主模塊。

另一個(gè)主要的區(qū)別是我們將 SettingsModule 模塊的主路徑設(shè)置為空路徑 (’’)。因?yàn)槿绻覀兟窂皆O(shè)置為 /settings ,它將匹配 /settings/settings ,很明顯這不是我們想要的結(jié)果。通過(guò)指定一個(gè)空的路徑,它就會(huì)匹配 /settings 路徑,這就是我們想要的結(jié)果。

那么 /settings 路由信息,需要在哪里配置?答案是在 AppModule 中。這時(shí)我們就需要用到 loadChildren 屬性,具體如下:

export const ROUTES: Routes = [
  {
    path: 'settings',
    loadChildren: () => import('./settings/settings.module').then(it => it.SettingsModule)
  }
];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
  // ...
})
export class AppModule {}

需要注意的是,我們沒(méi)有將 SettingsModule 導(dǎo)入到我們的 AppModule 中,而是通過(guò) loadChildren 屬性,告訴 Angular 路由依據(jù) loadChildren 屬性配置的路徑去加載 SettingsModule 模塊。這就是模塊懶加載功能的具體應(yīng)用,當(dāng)用戶訪問(wèn) /settings/** 路徑的時(shí)候,才會(huì)加載對(duì)應(yīng)的 SettingsModule 模塊,這減少了應(yīng)用啟動(dòng)時(shí)加載資源的大小。

另外我們傳遞一個(gè)字符串作為 loadChildren 的屬性值,該字符串由三部分組成:

需要導(dǎo)入模塊的相對(duì)路徑
# 分隔符
導(dǎo)出模塊類的名稱

了解完路由的一些高級(jí)選項(xiàng)和功能,接下來(lái)我們來(lái)介紹路由指令。

Router Directives

除了 router-outlet 指令,路由模塊中還提供了一些其它指令。讓我們來(lái)看看它們?nèi)绾闻c我們之前介紹的內(nèi)容結(jié)合使用。

routerLink

為了讓我們鏈接到已設(shè)置的路由,我們需要使用 routerLink 指令,具體示例如下:

<nav>
  <a routerLink="/">Home</a>
  <a routerLink="/settings/password">Change password</a>
  <a routerLink="/settings/profile">Profile Settings</a>
</nav>

當(dāng)我們點(diǎn)擊以上的任意鏈接時(shí),頁(yè)面不會(huì)被重新加載。反之,我們的路徑將在 URL 地址欄中顯示,隨后進(jìn)行后續(xù)視圖更新,以匹配 routerLink 中設(shè)置的值。

友情提示:我們也可以將 routerLink 的屬性值,改成數(shù)組形式,以便我們傳遞特定的路由信息
如果我們想要鏈接到動(dòng)態(tài)的路由地址,且該地址有一個(gè) username 的路由變量,則我們可以按照以下方式配置 routerLink 對(duì)應(yīng)的屬性值:

<a [routerLink]="['/profile', username]">
  Go to {{ username }}'s profile.
</a>
routerLinkActive

在實(shí)際開(kāi)發(fā)中,我們需要讓用戶知道哪個(gè)路由處于激活狀態(tài),通常情況下我們通過(guò)向激活的鏈接添加一個(gè) class 來(lái)實(shí)現(xiàn)該功能。為了解決上述問(wèn)題,Angular 路由模塊為我們提供了 routerLinkActive 指令,該指令的使用示例如下:

<nav>
  <a routerLink="/settings" routerLinkActive="active">Home</a>
  <a routerLink="/settings/password" routerLinkActive="active">Change password</a>
  <a routerLink="/settings/profile" routerLinkActive="active">Profile Settings</a>
</nav>

通過(guò)使用 routerLinkActive 指令,當(dāng) a 元素對(duì)應(yīng)的路由處于激活狀態(tài)時(shí),active 類將會(huì)自動(dòng)添加到 a 元素上。
最后,我們來(lái)簡(jiǎn)單介紹一下 Router API。

Router API

我們可以通過(guò)路由還提供的 API 實(shí)現(xiàn)與 routerLink 相同的功能。要使用 Router API,我們需要在組件類中注入 Router 對(duì)象,具體如下:

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  template: `
    <div class="app">
      <h4>Our app</h4>
      <router-outlet></router-outlet>
    </div>
  `
})
export class AppComponent {
  constructor(private router: Router) {}
}

組件類中注入的 router 對(duì)象中有一個(gè) navigate() 方法,該方法支持的參數(shù)類型與 routerLink 指令一樣,當(dāng)調(diào)用該方法后,頁(yè)面將會(huì)自動(dòng)跳轉(zhuǎn)到對(duì)應(yīng)的路由地址。具體使用示例如下:

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

@Component({
  selector: 'app-root',
  template: `
    <div class="app">
      <h4>Our app</h4>
      <router-outlet></router-outlet>
    </div>
  `
})
export class AppComponent implements OnInit {
  constructor(private router: Router) {}
  ngOnInit() {
    setTimeout(() => {
      this.router.navigate(['/settings']);
    }, 5000);
  }
}

若以上代碼成功運(yùn)行,用戶界面將在 5 秒后被重定向到 /settings 頁(yè)面。這個(gè)方法非常有用,例如當(dāng)檢測(cè)到用戶尚未登錄時(shí),自動(dòng)重定向到登錄頁(yè)面。

另一個(gè)使用示例是演示頁(yè)面跳轉(zhuǎn)時(shí)如何傳遞數(shù)據(jù),具體如下:

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

@Component({
  selector: 'app-root',
  template: `
    <div class="app">
      <h4>Users</h4>
      <div *ngFor="let user of users">
        <user-component 
          [user]="user"
          (select)="handleSelect($event)">
        </user-component>
      </div>
      <router-outlet></router-outlet>
    </div>
  `
})
export class AppComponent implements OnInit {
  users: Username[] = [
    { name: 'toddmotto', id: 0 },
    { name: 'travisbarker', id: 1 },
    { name: 'tomdelonge', id: 2 }
  ];
  
  constructor(private router: Router) {}
  
  handleSelect(event) {
    this.router.navigate(['/profile', event.name]);
  }
}

Angular 路由的功能非常強(qiáng)大,既可以使用指令方式也可以使用命令式 API,希望本文可以幫助你盡快入門,若要進(jìn)一步了解路由詳細(xì)信息,請(qǐng)?jiān)L問(wèn) - Angular Router 官文文檔。

路由傳參示例
/router/823712312938123;h=h;c=c?code=code

  • HTML:

<a [routerLink]="['/router', '823712312938123', {h:'h',c:'c'}]"
     [queryParams]="{code:'code'}">RouterLink 跳轉(zhuǎn)</a>
  <a (click)="goToDetail()">Navigate 跳轉(zhuǎn)</a>
  • TS:

 this.router.navigate([`router/823712312938123`, {h: 'h', c: 'c'}],
      {queryParams: {code: 'code'}})

在component中取數(shù)據(jù)
router-demo.component.ts

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

@Component({
  selector: 'app-router-demo',
  templateUrl: './router-demo.component.html',
  styleUrls: ['./router-demo.component.less']
})
export class RouterDemoComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {
  }

  ngOnInit(): void {
    const {params, queryParams} = this.activatedRoute.snapshot
    console.log('params', params)
    console.log('queryParams', queryParams, queryParams)

  }

}

Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么

Angular Router API 提供了 navigate()navigateByUrl() 兩個(gè)方法來(lái)實(shí)現(xiàn)頁(yè)面導(dǎo)航。兩者區(qū)別如下:

  • 使用router.navigateByUrl() 方法與直接改變地址欄上的 URL 地址一樣,我們使用了一個(gè)新的 URL 地址。

  • 然而 router.navigate() 方法基于一系列輸入?yún)?shù),產(chǎn)生一個(gè)新的 URL 地址。

為了更好理解兩者區(qū)別,有例子,假設(shè)當(dāng)前的 URL 地址是:

/inbox/11/message/22(popup:compose)

當(dāng)調(diào)用 router.navigateByUrl('/inbox/33/message/44') 方法后,當(dāng)前的 URL 地址將變成/inbox/33/message/44 。

但若是調(diào)用 router.navigate('/inbox/33/message/44') 方法,當(dāng)前的 URL 地址將變成 /inbox/33/message/44(popup:compose)。

到此,關(guān)于“Angular中navigate()和navigateByUrl()使用方法的區(qū)別是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI