Angular 基础知识规整之路由

发布日期 目录 Angular

Angular 路由基础知识大纲

  1. 什么是路由
  2. 路由的基本用法
  3. 路由懒加载异步模块
  4. 嵌套路由
  5. 传递和获取路由参数

一、什么是路由

路由,百度百科这样说的:路由是指路由器从一个接口上收到数据包,根据数据路由包的目的地址进行定向并转发到另一个接口的过程。

当然,这个定义对我们来说没什么卵用。

说白了,路由就是网址,在浏览器输入网址后可以跳转到相应的页面。因为有了路由,也才有我们浏览器的前进与后退。如果没有路由,浏览器的前进后退按钮没法用;如果没有路由,你也将无法把URL拷贝并分享给你的朋友。

目前已是21世纪,开发模式已是前后端分离开发,前端只需要向后端请求数据即可。那路由这块就可能需要前端来做,这时就有了前端路由与后端路由之分。这里只说angular 的路由。

Angular 单页面应用开发,由于所有的内容都在一个页面上,想跳转不同的页面,就需要使用网址的哈希(即 # 号)来做处理,即控制哪一部分内容在单页面上显示,从而达到看起来是多页面的目的。

二、路由的基本用法

首先,明白路由要写在什么地方?

一般情况下,为了方便管理 我们都单独起一个路由文件(如文件名:app.routes.ts)。当然也可以写在模块里面,不过不建议这样做。

那这个文件如何写呢?

// app.routes.ts
// 引入路由模块
import { RouterModule } from '@angular/router';
// 引入 home 组件
import {HomeComponent} from './home/home.component';
// 引入 jokes 组件
import {JokesComponent} from './jokes/jokes.component';

export const appRoutes=[
    {
        path:'',    // 路由为空
        redirectTo:'home',    // 重定向到 home 
        pathMatch:'full'    // 全匹配
    },
    {
        path:'home',    // home 路由地址
        component:HomeComponent    // home 地址对应的组件。页面显示该组件对应的html模板内容
    },
    {
        path:'jokes',
        component:JokesComponent
    },
    {
        path:'**',    // 输入不存在的路由
        component:HomeComponent    // 跳转 home 组件,即页面显示home组件的html模板内容
    }
];

可以看出来,路由基本是对应着组件来的,组件里面有 html 模板。即一个路由指向一个组件,一个组件指向一个模板,从而实现不同页面对应不同路由。

创建了路由文件,要让其工作起来,也就是能用,这里还需要做其他的事情。

首先,要导入到组件对应的模块中去,我这里对应着 app.module.ts 该模块,那我就需要把路由文件导入进去。

看一下引入路由之后的模块:

// app.module.ts
import { NgModule } from '@angular/core';
// 1、引入 路由 模块 RouterModule
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
// 2、引入我们创建的路由文件 appRoutes
import { appRoutes } from './app.routes';
import { HomeComponent } from './home/home.component';
import { JokesComponent } from './jokes/jokes.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    JokesComponent
  ],
  imports: [
    BrowserModule,
    // 3、将我们创建的路由文件引入到路由模块中去
    RouterModule.forRoot(appRoutes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

一般切换不同的页面有不同的按钮,我们还要在导航的按钮添加点击跳转,这一般都是在 html 模板上面动手脚。

现在看我们的 html 模板里面的路由相关属性:

<!--app.component.html-->
<ul>
    <li routerLinkActive="active">
        <a routerLink="home">主页</a>
    </li>
    <li routerLinkActive="active">
        <a routerLink="jokes">段子</a>
    </li>
</ul>
<div class="container">
  <router-outlet></router-outlet>
  <!--路由加载的 html 模板内容会放到该行-->
</div>

上面的 routerLink=”jokes” 属性是点击后跳转的路由,routerLinkActive=”active” 属性意思是如果当前路由为激活状态,则显示 “active” CSS样式类

这个标签的作用是,让路由加载的 html 模板内容显示在这个标签下面。相当于是占位符。

这样我们一个最基本的路由就可以正常工作了。

三、路由懒加载模块

在上面路由的基本用法里面,路由都是去加载组件,但是我们的项目里面不光有组件,还有其他的模块,那路由如何去加载模块?

路由加载模块,这里还有好处,我们先来说下这个好处,再贴代码。
一般都知道,现在的web工程都会使用打包工具,像webpack、gulp等。他们会把所有的同类型文件,打包成一个文件,这就导致我们的代码文件的大小会很大。angular 中利用模块的机制,可以使 angular-cli 打包时,将不同的模块的代码打包在一起,这样页面在加载时会先加载主模块包的代码,等到用的其他模块的代码时在加载对应的其他模块包的代码。

这样我们可以利用路由,去异步加载我们其他模块的代码,即懒加载异步模块。

如何去写,看代码,比如在app.routes.ts里面加载一个模块:

// app.routes.ts
import { RouterModule } from '@angular/router';

export const appRoutes=[
    {
        path:'',
        redirectTo:'home',
        pathMatch:'full'
    },
    {
        path:'home',    // 路由地址
        loadChildren:'./home/home.module#HomeModule'    // 这样写法便指向一个模块
    },
    {
        path:'jokes',
        loadChildren:'./jokes/jokes.module#JokesModule'   // 另外一个模块
    }
];

关于模块的用法,这里不说,这里只说路由。路由里面指向一个模块之后,该模块还会有相应的路由,分别指向不同的组件。

指向的模块里面还会引入创建的路由文件,在生成路由的写法有点不同:

// home.module.ts
...

@NgModule({
  declarations: [
    HomeComponent,
    ...
  ],
  imports: [
    // 之前是 forRoot,现在是 forChild 
    RouterModule.forChild(homeRoutes)
  ],
  providers: [],
})
export class HomeModule { }

这里除了注入路由的方法(forChild)不同,其他都一样。这样便利用路由完成了懒加载模块。

四、嵌套路由

其实在上面的异步模块中,我们已经完成了一个子路由,主路由指向一个模块,模块又带有一个路由,这其实已经嵌套一层路由了。但是我们还可以在嵌套的子路由里面,不用加载模块再嵌套一层路由。

看例子:

// home.routes.ts
import { RouterModule } from '@angular/router';
import { HomeComponent } from './home.component';
import { PictureComponent } from './picture/picture.component';
import { TextComponent } from './text/text.component';

export const homeRoutes=[
    {
        path:'',
        component:HomeComponent,
        children:[   // 这里面是子路由
            {
                path:'',
                redirectTo:'pictures',
                pathMatch:'full'
            },
            {
                path:'pictures',
                component:PictureComponent
            },
            {
                path:'text',
                component:TextComponent
            }
        ]
    }
];

五、传递与获取路由参数

平时开发,我们会经常用路由去传递参数,举个业务场景:有个表格,每行后面跟个详情,点击详情,跳转详情页面,这时我们一般会把数据id随路由(链接)传递给详情页面,查询出该数据的具体详情。

那如何用路由去传递与获取参数呢?

1、传递单个参数:
  • 当前路由 html 模板里面:
...
<div>
    <a [routerLink]="['detail','1']">详情</a>
</div>
...
  • routes里面:
...
{
    path:'detail/:id',
    component:DetailComponent
},
...
  • 路由 目标组件 里面获取参数:
import { Component, OnInit } from '@angular/core';
// 引入 ActivatedRoute 方法
import { ActivatedRoute } from '@angular/router';

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

  constructor(
  // 注入 ActivatedRoute 方法
    public activeRoute: ActivatedRoute
  ) { }

  ngOnInit() {
    // this.activeRoute.params 是 Observable 对象,用subscribe订阅它。这是rxjs的东西,这里先了解怎么获取参数
    this.activeRoute.params.subscribe(
      (params)=>{console.log(params)}
    );

  }

}

2、传递多个参数
  • 当前路由 html 模板里面:
...
<div>
    <a [routerLink]="['detail',{id:111,name:'damo'}]">详情</a>
</div>
...
  • routes里面:
...
{
    path:'detail',
    component:DetailComponent
},
...
  • 路由 目标组件 里面获取参数:
import { Component, OnInit } from '@angular/core';
// 引入 ActivatedRoute 方法
import { ActivatedRoute } from '@angular/router';

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

  constructor(
    // 注入 ActivatedRoute 方法
    public activeRoute: ActivatedRoute
  ) { }

  ngOnInit() {
    this.activeRoute.queryParams.subscribe(
      (queryParam)=>{console.log(queryParam)}
    );
  }

}

当然,我们除了在html模板里面传递参数之外,还可以在我们的组件里面通过代码去传递参数。

  • 路由对应 html 模板:
...
<div>
    <button (click)="toDetail()">详情</button>
</div>
...
  • routes里面:
...
{
    path:'detail',
    component:DetailComponent
},
...
  • 路由组件里面
import { Component, OnInit } from '@angular/core';
// 引入 Router 方法
import { Router } from '@angular/router';

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

  constructor(
    // 注入 Router 方法
    public router: Router
  ) { }

  ngOnInit() {
  }

  toDetail(){
  // 这里传多个参数,也可以传一个参数,格式一样的
    this.router.navigate(["/detail"],{ queryParams: { id: 1,name:"222" } });
  }

}

  • 路由目标组件:
...
// 还是用 queryParams 来接收参数
this.activeRoute.queryParams.subscribe(
    (queryParam)=>{console.log(queryParam)}
);
...

至此路由的基础知识,这里就将结束了。

原文: http://blog.seebin.com/2017/08/21/angular-routes/

发表评论

邮箱地址不会被公开。