2.ng-zorro项目路由

687 阅读4分钟

项目概况

该项目是一个简单的后台管理系统,包含头部(logo + 用户),侧边栏(种族/race、职业/profession、用户/user、权限/permission),展示内容页面。

1.创建侧边栏模块

打开文件夹进入src/app/routes文件夹,执行生成命令

ng g m race --routing
ng g c race/race-list

ng g m profession --routing
ng g c profession/profession-list

ng g m user --routing
ng g c user/user-list

ng g m permission --routing
ng g c permission/permission-list

执行完成后,生成对应模块、路由模块和list组件,并且list组件已注入到对应模块中。

2.修改路由配置

修改各模块的路由文件,将list组件引入,写进路由中:

import { Routes, RouterModule } from '@angular/router';
import { RaceListComponent } from './race-list/race-list.component';

const routes: Routes = [
  { path: '', component: RaceListComponent }
];

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

模块修改完成后,修改根路由routes-routing.module.ts文件,将各个子模块异步加载引入

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

const routes: Routes = [
  { path: 'race', loadChildren: () => import('./race/race.module').then(mod => mod.RaceModule) },
  { path: 'profession', loadChildren: () => import('./profession/profession.module').then(mod => mod.ProfessionModule) },
  { path: 'user', loadChildren: () => import('./user/user.module').then(mod => mod.UserModule) },
  { path: 'permission', loadChildren: () => import('./permission/permission.module').then(mod => mod.PermissionModule) },
];

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

配置完成后,打开浏览器输入对应的路由就能进入对应list组件中:

http://localhost:4200/user
http://localhost:4200/race

注意:

  • 把每个路由写进对应模块,新增当前模块子路由时不需在根路由中体现,根路由更加简洁
  • 各个模块异步加载,可以提高首屏加载速度
  • 子模块的路由都使用forChild(),根路由中必须使用RouterModule.forRoot(),每个项目只能存在一个forRoot。
3.修改layout模块,新增头部和侧边栏页面

进入layout文件夹,运行命令生成默认布局组件和登录布局组件。

ng g c default
ng g c passport

布局页面参考ng-zorro官网layout布局(ng.ant.design/components/…

default.component.html
<nz-layout class="app-container">
    <nz-header>
        <div class="header-container">
            <div class="logo">logo</div>
            <div class="user-setting">
                <span>{{username}}</span>
                <nz-divider nzType="vertical"></nz-divider>
                <a nz-button nzType="link" (click)="logout()">退出</a>
            </div>
        </div>
    </nz-header>
    <nz-layout>
        <nz-sider nzWidth="200px" nzTheme="light">
            <ul nz-menu nzMode="inline">
                <li nz-menu-item [nzMatchRouter]="true">
                    <a routerLink="/race"><i nz-icon nzType="user" nzTheme="outline"></i>种族</a>
                </li>
                <li nz-menu-item [nzMatchRouter]="true">
                    <a routerLink="/profession"><i nz-icon nzType="user" nzTheme="outline"></i>职业</a>
                </li>
                <li nz-menu-item [nzMatchRouter]="true">
                    <a routerLink="/user"><i nz-icon nzType="user" nzTheme="outline"></i>用户</a>
                </li>
                <li nz-menu-item [nzMatchRouter]="true">
                    <a routerLink="/permission"><i nz-icon nzType="user" nzTheme="outline"></i>权限</a>
                </li>
            </ul>
        </nz-sider>
        <nz-content class="content-container">
            <router-outlet></router-outlet>
        </nz-content>
    </nz-layout>
</nz-layout>
default.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-default',
  templateUrl: './default.component.html',
  styleUrls: ['./default.component.css']
})
export class DefaultComponent implements OnInit {

  username = 'admin';

  constructor() { }

  ngOnInit(): void {
  }

  logout(): void {
    // 退出登录
  }

}
default.component.css
:host .app-container {
    height: 100Vh;
}

:host .content-container {
    position: relative;
    height: calc(100vh - 50px);
}

:host .ant-layout-header {
    height: 48px;
    line-height: 48px;
    padding: 0 6px;
    background-color: #0747a6;
}

:host .header-container {
    display: flex;
    justify-content: space-between;
    color: #ffffff;
}

修改完default组件后,组件内页面会提示nz-layout不是angular组件,这时需要将ng-zorro引入模块。

如果之前已经运行过ng add ng-zorro-antd,没有话需要运行一下,然后直接在shared模块中引入对应所需模块。

注:一定要确保angular版本和zorro版本兼容,不然会出奇怪问题

shared.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';

import { UserOutline } from '@ant-design/icons-angular/icons';
import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzDividerModule } from 'ng-zorro-antd/divider';
import { NzMenuModule } from 'ng-zorro-antd/menu';
import { NzIconModule } from 'ng-zorro-antd/icon';


// 引入zorro图标
const icons = [
  UserOutline
];

// angular模块
const ANGULARMODULE = [
  CommonModule,
  FormsModule,
  RouterModule,
];

// ng-zorro模块
const NGZORROMODULE = [
  NzIconModule.forRoot(icons),
  NzLayoutModule,
  NzButtonModule,
  NzDividerModule,
  NzMenuModule
];

// 公共组件
const COMPONENTS = [];
// 公共服务
const SERVICES = [];
// 公共管道
const PIPES = [];
// 公共指令
const DIRECTIVES = [];


@NgModule({
  imports: [
    ...ANGULARMODULE,
    ...NGZORROMODULE
  ],
  declarations: [
    ...COMPONENTS,
    ...DIRECTIVES,
    ...PIPES,
  ],
  providers: [...SERVICES],
  exports: [
    ...ANGULARMODULE,
    ...NGZORROMODULE,
    ...COMPONENTS,
    ...DIRECTIVES,
  ]
})
export class SharedModule { }

zorro官网建议按需引入,等后面需要的时候再到NGZORROMODULE中添加。

zorro的图标也是如此,在icon中添加后才能在页面上展示出来

zorro引入到shared模块后,将shared模块引入到layout模块中,页面就不会报非angular组件的错。

layout.module.ts
import { NgModule } from '@angular/core';
import { SharedModule } from '@shared/shared.module';
import { DefaultComponent } from './default/default.component';
import { PassportComponent } from './passport/passport.component';

@NgModule({
  declarations: [DefaultComponent, PassportComponent],
  imports: [
    SharedModule
  ]
})
export class LayoutModule { }

此时已经将头部和侧边栏的组件写完,加载到项目中展示即可。

再次修改根路由routes-routing.module.ts,将原先组件设置成default组件的子路由。

routes-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DefaultComponent } from '@layout/default/default.component';

const routes: Routes = [
  {
    path: '',
    component: DefaultComponent,
    children: [
      { path: 'race', loadChildren: () => import('./race/race.module').then(mod => mod.RaceModule) },
      { path: 'profession', loadChildren: () => import('./profession/profession.module').then(mod => mod.ProfessionModule) },
      { path: 'user', loadChildren: () => import('./user/user.module').then(mod => mod.UserModule) },
      { path: 'permission', loadChildren: () => import('./permission/permission.module').then(mod => mod.PermissionModule) },
    ]
  },
];

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

此时打开浏览器,就可以看到页面上展示头部和侧边栏,还有点击侧边栏可变的中间部分。

http://localhost:4200/

执行ng add ng-zorro-antd后,会修改部分文件,并将ng-zorro的样式更新到angular.json的配置文件中,需要重新执行ng serve才能展示出来项目。

将app.module.ts修改的部分移入core.module.ts中,此时的中英文只对日期类的组件有效,不写会导致日期类组件值出错。

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

import { AppComponent } from './app.component';
import { RoutesModule } from '@routes/routes.module';
import { LayoutModule } from '@layout/layout.module';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    RouterModule,
    LayoutModule,
    RoutesModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
core.module.ts
import { NgModule } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import { NZ_I18N, zh_CN } from 'ng-zorro-antd/i18n';
import zh from '@angular/common/locales/zh';

registerLocaleData(zh);

@NgModule({
  declarations: [],
  imports: [],
  providers: [
    { provide: NZ_I18N, useValue: zh_CN }
  ]
})
export class CoreModule { }