Angular 基础知识规整之路由

来源:互联网 发布:ae数字矩阵 特效 编辑:程序博客网 时间:2024/05/29 04:40

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.tsimport { NgModule } from '@angular/core';// 1、引入 路由 模块 RouterModuleimport { RouterModule } from '@angular/router';import { BrowserModule } from '@angular/platform-browser';import { AppComponent } from './app.component';// 2、引入我们创建的路由文件 appRoutesimport { 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.tsimport { 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.tsimport { 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/