0

0

浅谈Angular中navigate()和navigateByUrl()使用方法的区别

青灯夜游

青灯夜游

发布时间:2021-06-25 11:55:46

|

2942人浏览过

|

来源于csdn

转载

路由是angular应用程序的核心,本篇文章带大家了解一下angular router,详细介绍一下navigate()和navigatebyurl()用法的区别。

浅谈Angular中navigate()和navigateByUrl()使用方法的区别

路由是 Angular 应用程序的核心,它加载与所请求路由相关联的组件,以及获取特定路由的相关数据。这允许我们通过控制不同的路由,获取不同的数据,从而渲染不同的页面。【相关教程推荐:《angular教程》】

Installing the router

首先第一件事,我们需要安装 Angular Router。你可以通过运行以下任一操作来执行此操作:

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

以上命令执行后,将会自动下载 @angular/router 模块到 node_modules 文件夹中。

Base href

我们需要做的最后一件事,是将 标签添加到我们的 index.html 文件中。路由需要根据这个来确定应用程序的根目录。例如,当我们转到 http://example.com/page1 时,如果我们没有定义应用程序的基础路径,路由将无法知道我们的应用的托管地址是 http://example.com 还是 http://example.com/page1

这件事操作起来很简单,只需打开项目中的 index.html 文件,添加相应的 标签,具体如下:



  
    
    Application
  
  
    
  

以上配置信息告诉 Angular 路由,应用程序的根目录是 /

Using the router

要使用路由,我们需要在 AppModule 模块中,导入 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 {}

此时我们的路由还不能正常工作,因为我们还未配置应用程序路由的相关信息。RouterModule 对象为我们提供了两个静态的方法:forRoot()forChild() 来配置路由信息。

RouterModule.forRoot()

RouterModule.forRoot() 方法用于在主模块中定义主要的路由信息,通过调用该方法使得我们的主模块可以访问路由模块中定义的所有指令。接下来我们来看一下如何使用 forRoot()

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

export const ROUTES: Routes = [];

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

我们通过使用 const 定义路由的配置信息,然后把它作为参数调用 RouterModule.forRoot() 方法,而不是直接使用 RouterModule.forRoot([...]) 这种方式,这样做的好处是方便我们在需要的时候导出 ROUTES 到其它模块中。

RouterModule.forChild()

RouterModule.forChild()Router.forRoot() 方法类似,但它只能应用在特性模块中。
友情提示:根模块中使用 forRoot(),子模块中使用 forChild()
这个功能非常强大,因为我们不必在一个地方(我们的主模块)定义所有路由信息。反之,我们可以在特性模块中定义模块特有的路由信息,并在必要的时候将它们导入我们主模块。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 {}

通过以上示例,我们知道在主模块和特性模块中,路由配置对象的类型是一样的,区别只是主模块和特性模块中需调用不同的方法,来配置模块路由。接下来我们来介绍一下如何配置 ROUTES 对象。

Configuring a route

我们定义的所有路由都是作为 ROUTES 数组中的对象。首先,为我们的主页定义一个路由:

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 {}

示例中我们通过 path 属性定义路由的匹配路径,而 component 属性用于定义路由匹配时需要加载的组件。

友情提示:我们使用 path: '' 来匹配空的路径,例如:https://yourdomain.com

Displaying routes

配置完路由信息后,下一步是使用一个名为 router-outlet 的指令告诉 Angular 在哪里加载组件。当 Angular 路由匹配到响应路径,并成功找到需要加载的组件时,它将动态创建对应的组件,并将其作为兄弟元素,插入到 router-outlet 元素中。

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

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

@Component({
  selector: 'app-root',
  template: `
    

Our app

` }) export class AppComponent {}

我们现在已经建立了应用程序的主路由,我们可以进一步了解路由的其它配置选项。

Further configuration

到目前为止我们已经介绍的内容只是一个开始 ,接下来我们来看看其它一些选项和功能。

Dynamic routes

如果路由始终是静态的,那没有多大的用处。例如 path: '' 是加载我们 HomeComponent 组件的静态路由。我们将介绍动态路由,基于动态路由我们可以根据不同的路由参数,渲染不同的页面。

例如,如果我们想要在个人资料页面根据不同的用户名显示不同的用户信息,我们可以使用以下方式定义路由:

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

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

这里的关键点是 : ,它告诉 Angular 路由,:username 是路由参数,而不是 URL 中实际的部分。

友情提示:如果没有使用 : ,它将作为静态路由,仅匹配 /profile/username 路径
现在我们已经建立一个动态路由,此时最重要的事情就是如何获取路由参数。要访问当前路由的相关信息,我们需要先从 @angular/router 模块中导入 ActivatedRoute ,然后在组件类的构造函数中注入该对象,最后通过订阅该对象的 params 属性,来获取路由参数,具体示例如下:

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

@Component({
  selector: 'profile-page',
  template: `
    

{{ username }}

` }) export class SettingsComponent implements OnInit { username: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.params.subscribe((params) => this.username = params.username); } }

介绍完动态路由,我们来探讨一下如何创建 child routes。

Child routes

实际上每个路由都支持子路由,假设在我们 /settings 设置页面下有 /settings/profile/settings/password 两个页面,分别表示个人资料页和修改密码页。

我们可能希望我们的 /settings 页面拥有自己的组件,然后在设置页面组件中显示 /settings/profile/settings/password 页面。我们可以这样做:

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 {}

在这里,我们在 setttings 路由中定义了两个子路由,它们将继承父路由的路径,因此修改密码页面的路由匹配地址是 /settings/password ,依此类推。

接下来,我们需要做的最后一件事是在我们的 SettingsComponent 组件中添加 router-outlet 指令,因为我们要在设置页面中呈现子路由。如果我们没有在 SettingsComponent 组件中添加 router-outlet 指令,尽管 /settings/password 匹配修改密码页面的路由地址,但修改密码页面将无法正常显示。具体代码如下:

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

@Component({
  selector: 'settings-page',
  template: `
    
` }) export class SettingsComponent {}

Component-less routes

另一个很有用的路由功能是 component-less 路由。使用 component-less 路由允许我们将路由组合在一起,并让它们共享路由配置信息和 outlet。

腾讯云AI代码助手
腾讯云AI代码助手

基于混元代码大模型的AI辅助编码工具

下载

例如,我们可以定义 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 {}

此时, /settings/profile/settings/password 路由定义的内容,将显示在 AppComponent 组件的 router-outlet 元素中。

loadChildren

我们也可以告诉路由从另一个模块中获取子路由。这将我们谈论的两个想法联系在一起 - 我们可以指定另一个模块中定义的子路由,以及通过将这些子路由设置到特定的路径下,来充分利用 component-less 路由的功能。

让我们创建一个 SettingsModule 模块,用来保存所有 setttings 相关的路由信息:

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() 方法,因为 SettingsModule 不是我们应用的主模块。

另一个主要的区别是我们将 SettingsModule 模块的主路径设置为空路径 (’’)。因为如果我们路径设置为 /settings ,它将匹配 /settings/settings ,很明显这不是我们想要的结果。通过指定一个空的路径,它就会匹配 /settings 路径,这就是我们想要的结果。

那么 /settings 路由信息,需要在哪里配置?答案是在 AppModule 中。这时我们就需要用到 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 {}

需要注意的是,我们没有将 SettingsModule 导入到我们的 AppModule 中,而是通过 loadChildren 属性,告诉 Angular 路由依据 loadChildren 属性配置的路径去加载 SettingsModule 模块。这就是模块懒加载功能的具体应用,当用户访问 /settings/** 路径的时候,才会加载对应的 SettingsModule 模块,这减少了应用启动时加载资源的大小。

另外我们传递一个字符串作为 loadChildren 的属性值,该字符串由三部分组成:

需要导入模块的相对路径
# 分隔符
导出模块类的名称

了解完路由的一些高级选项和功能,接下来我们来介绍路由指令。

Router Directives

除了 router-outlet 指令,路由模块中还提供了一些其它指令。让我们来看看它们如何与我们之前介绍的内容结合使用。

routerLink

为了让我们链接到已设置的路由,我们需要使用 routerLink 指令,具体示例如下:

当我们点击以上的任意链接时,页面不会被重新加载。反之,我们的路径将在 URL 地址栏中显示,随后进行后续视图更新,以匹配 routerLink 中设置的值。

友情提示:我们也可以将 routerLink 的属性值,改成数组形式,以便我们传递特定的路由信息
如果我们想要链接到动态的路由地址,且该地址有一个 username 的路由变量,则我们可以按照以下方式配置 routerLink 对应的属性值:


  Go to {{ username }}'s profile.

routerLinkActive

在实际开发中,我们需要让用户知道哪个路由处于激活状态,通常情况下我们通过向激活的链接添加一个 class 来实现该功能。为了解决上述问题,Angular 路由模块为我们提供了 routerLinkActive 指令,该指令的使用示例如下:

通过使用 routerLinkActive 指令,当 a 元素对应的路由处于激活状态时,active 类将会自动添加到 a 元素上。
最后,我们来简单介绍一下 Router API。

Router API

我们可以通过路由还提供的 API 实现与 routerLink 相同的功能。要使用 Router API,我们需要在组件类中注入 Router 对象,具体如下:

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

@Component({
  selector: 'app-root',
  template: `
    

Our app

` }) export class AppComponent { constructor(private router: Router) {} }

组件类中注入的 router 对象中有一个 navigate() 方法,该方法支持的参数类型与 routerLink 指令一样,当调用该方法后,页面将会自动跳转到对应的路由地址。具体使用示例如下:

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

@Component({
  selector: 'app-root',
  template: `
    

Our app

` }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit() { setTimeout(() => { this.router.navigate(['/settings']); }, 5000); } }

若以上代码成功运行,用户界面将在 5 秒后被重定向到 /settings 页面。这个方法非常有用,例如当检测到用户尚未登录时,自动重定向到登录页面。

另一个使用示例是演示页面跳转时如何传递数据,具体如下:

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

@Component({
  selector: 'app-root',
  template: `
    

Users

` }) 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 路由的功能非常强大,既可以使用指令方式也可以使用命令式 API,希望本文可以帮助你尽快入门,若要进一步了解路由详细信息,请访问 - Angular Router 官文文档。

路由传参示例
/router/823712312938123;h=h;c=c?code=code

  • HTML:
RouterLink 跳转
  Navigate 跳转
  • TS:
 this.router.navigate([`router/823712312938123`, {h: 'h', c: 'c'}],
      {queryParams: {code: 'code'}})

在component中取数据
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)

  }

}

router取数据

Angular Router API 提供了 navigate()navigateByUrl() 两个方法来实现页面导航。两者区别如下:

  • 使用router.navigateByUrl() 方法与直接改变地址栏上的 URL 地址一样,我们使用了一个新的 URL 地址。
  • 然而 router.navigate() 方法基于一系列输入参数,产生一个新的 URL 地址。

为了更好理解两者区别,有例子,假设当前的 URL 地址是:

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

当调用 router.navigateByUrl('/inbox/33/message/44') 方法后,当前的 URL 地址将变成/inbox/33/message/44

但若是调用 router.navigate('/inbox/33/message/44') 方法,当前的 URL 地址将变成 /inbox/33/message/44(popup:compose)

更多编程相关知识,请访问:编程入门!!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Sass和less的区别
Sass和less的区别

Sass和less的区别有语法差异、变量和混合器的定义方式、导入方式、运算符的支持、扩展性等。本专题为大家提供Sass和less相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.10.12

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

531

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

319

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

653

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

609

2024.04.29

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

7

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue.js:纪录片
Vue.js:纪录片

共1课时 | 0.2万人学习

Angular js入门篇
Angular js入门篇

共17课时 | 3.5万人学习

uni-app电商系统实战精讲课程
uni-app电商系统实战精讲课程

共66课时 | 15.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号