3
前言:单页应用中,组件时构建应用的基础元素,页面展示什么内容均是靠页面有什么组件决定的,而展示什么组件又是由一组路由(带有Url元素的特定集合,可用于导航视图)决定的,希望本文可以帮助读者了解路由的基础概念和基础使用、写法。

简单的路由配置

路由模块 app-routing.module.ts
构建一个简单的企业常用官网案例,通常这类网站头部与底部基本是固定得纯html,涉及动态改变的部分(颜色、内容)才和路由扯上关系。

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IndexComponent } from './component/index/index.component';
import { AboutComponent } from './component/about/about.component';
import { ContactComponent } from './component/contact/contact.component';
import { NewsComponent } from './component/news/news.component';

// 假设只有一级导航
const routes: Routes = [
  // 避免进入网站中间内容部分空白,设置默认导航
  {
    path: '',
    redirectTo: 'index',
    pathMatch: 'full'
  },
  {
    path: 'index',
    component: IndexComponent,
    data: {
      title: '公司主页'
    }
  },
  {
    path: 'about',
    component: AboutComponent,
    data: {
      title: '关于我们'
    }
  },
  {
    path: 'contact',
    component: ContactComponent,
    data: {
      title: '联系我们'
    }
  },
  {
    path: 'news',
    component: NewsComponent,
    data: {
      title: '公司动态'
    }
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

在App模块的声明数组中加入所需导航的全部组件(Angular目前脚手架会自动帮添加创建的组件到根模块或者指定模块);
App组件的模板:

<!-- NG-ZORRO -->
<app-header></app-header>
<div nz-row class="main">
  <div nz-col nzSpan="24">
    <router-outlet></router-outlet>
  </div>
</div>
<app-footer></app-footer>

目前路由到视图之间的映射关系基本确定,还需要提供下html中链接导航如何实现,代码如下:
header.component.html

<div nz-row class="app-header">
  <div nz-col nzSpan="6"></div>
  <div nz-col nzSpan="4" class="logo">
    <img src="assets/logo.png" alt="">
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/']" routerLinkActive="router-link-active">首页</a>
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/about']" routerLinkActive="router-link-active">公司简介</a>
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/news']" routerLinkActive="router-link-active">公司动态</a>
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/contact']" routerLinkActive="router-link-active">联系我们</a>
  </div>
  <div nz-col nzSpan="6"></div>
</div>

clipboard.png
路由配置这里还欠缺一个异常路由处理

core.js:9110 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'about123'
Error: Cannot match any routes. URL Segment: 'about123'

将下面的代码添加到路由配置最后

{
    path: 'error',
    component: ErrorComponent,
    data: {
      title: '参数错误或者地址不存在'
    }
  },
  {
    path: '**',
    redirectTo: 'error',
    pathMatch: 'full'
  }

clipboard.png

多级路由配置

需求:公司动态改成新闻动态-行业新闻和公司新闻

{
    path: 'news',
    component: NewsComponent,
    children: [
      {
        path: '',
        redirectTo: 'hyxw',
        pathMatch: 'full'
      },
      {
        path: 'hyxw',
        component: HyxwComponent,
        data: {
          title: '行业新闻'
        }
      },
      {
        path: 'gsxw',
        component: GsxwComponent,
        data: {
          title: '公司新闻'
        }
      }
    ]
  }

header.component.html

<div nz-row class="app-header">
  <div nz-col nzSpan="6"></div>
  <div nz-col nzSpan="4" class="logo">
    <img src="assets/logo.png" alt="">
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/']" routerLinkActive="router-link-active">首页</a>
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/about']" routerLinkActive="router-link-active">公司简介</a>
  </div>
  <div nz-col nzSpan="2">
    <a nz-dropdown [nzDropdownMenu]="menu">新闻动态</a>
  </div>
  <div nz-col nzSpan="2">
    <a [routerLink]="['/contact']" routerLinkActive="router-link-active">联系我们</a>
  </div>
  <div nz-col nzSpan="6"></div>
  <nz-dropdown-menu #menu="nzDropdownMenu">
    <ul nz-menu nzSelectable>
      <li nz-menu-item>
        <a [routerLink]="['/news/hyxw']" routerLinkActive="router-link-active">行业新闻</a>
      </li>
      <li nz-menu-item>
        <a [routerLink]="['/news/gsxw']" routerLinkActive="router-link-active">公司新闻</a>
      </li>
    </ul>
  </nz-dropdown-menu>
</div>

news.component.html

<div class="app-news">
  <router-outlet></router-outlet>
</div>

clipboard.png

路由懒加载

当然我们使用这么高级得框架只是做一个这么静态得企业官网是真的有点秀了,实际项目中页面内容和组件繁多,如果不使用懒加载,整个应用首次渲染会很耗时,如同整个页面图片全部渲染和懒加载图片模式一样,我们得路由模式中也是可以配置懒加载得。
修改如下:
app路由和根模块

const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./pages/pages.module').then(m => m.PagesModule)
  },
  {
    path: 'error',
    component: ErrorComponent,
    data: {
      title: '参数错误或者地址不存在'
    }
  },
  {
    path: '**',
    redirectTo: 'error',
    pathMatch: 'full'
  }
];
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';
import { CommonInterceptor } from './core/core/interceptor';
import { ErrorComponent } from './error/error.component';
import { HeaderComponent } from './component/header/header.component';
import { FooterComponent } from './component/footer/footer.component';

registerLocaleData(zh);

@NgModule({
  declarations: [
    AppComponent,
    ErrorComponent,
    HeaderComponent,
    FooterComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgZorroAntdModule,
    FormsModule,
    HttpClientModule,
    BrowserAnimationsModule
  ],
  providers: [
    { provide: NZ_I18N, useValue: zh_CN },
    { provide: HTTP_INTERCEPTORS, useClass: CommonInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

pages路由模块和pages模块

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IndexComponent } from '../component/index/index.component';
import { AboutComponent } from '../component/about/about.component';
import { ContactComponent } from '../component/contact/contact.component';
import { NewsComponent } from '../component/news/news.component';
import { HyxwComponent } from '../component/hyxw/hyxw.component';
import { GsxwComponent } from '../component/gsxw/gsxw.component';


const routes: Routes = [
  {
    path: '',
    redirectTo: 'index',
    pathMatch: 'full'
  },
  {
    path: 'index',
    component: IndexComponent,
    data: {
      title: '公司主页'
    }
  },
  {
    path: 'about',
    component: AboutComponent,
    data: {
      title: '关于我们'
    }
  },
  {
    path: 'contact',
    component: ContactComponent,
    data: {
      title: '联系我们'
    }
  },
  {
    path: 'news',
    loadChildren: () => import('../component/news/news.module').then(m => m.NewsModule)
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class PagesRoutingModule { }

pages模块:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { PagesRoutingModule } from './pages-routing.module';
import { PagesComponent } from './pages.component';
import { IndexComponent } from '../component/index/index.component';
import { AboutComponent } from '../component/about/about.component';
import { ContactComponent } from '../component/contact/contact.component';


@NgModule({
  declarations: [
    PagesComponent,
    IndexComponent,
    AboutComponent,
    ContactComponent,
  ],
  imports: [
    CommonModule,
    PagesRoutingModule
  ],
  bootstrap: [PagesComponent]
})
export class PagesModule { }

news路由和模块参照pages即可,改造前后首页渲染截图对比:

clipboard.png

clipboard.png

这样的路由配置基本就是一个项目的路由雏形了,下一篇会加入路由守卫的功能,文笔不是很好,可以的话希望路过的看官可以给个赞或者批评。


何弃疗
106 声望7 粉丝

前端路上摸爬滚打;野路子前端debug