在上一期博客中,我们建立了第一个angular项目,并介绍了angular项目中的重要文件。在这期博客中,我们开始安装重要的第三方插件,并开始编写我们的第一个angular组件。
六 使用npm命令安装第三方组件
我们首先来安装NG-ZORRO,这是一个遵循Ant Design设计规范的Angular UI组件库,提供了非常多的常用组件,任何组织、企业和个人均可免费使用。我们在cmd中进入到项目目录,输入以下命令来安装NG-ZORRO:
npm install ng-zorro-antd@11 --save
这里使用–save参数的含义是,将ng-zorro-antd库安装到项目里的node_modules目录中,并将其添加到package.json的dependencies属性下。 稍等一会,如果出现以下画面,说明ng-zorro-antd安装完成:  接下来,继续安装ngx-cookie-service,我们要使用这个库来操作cookies。在cmd中输入以下命令:
npm install ngx-cookie-service@11 --save
这里我们选择11版,和我们的angular版本保持一致。 然后,让我们安装ngx-quill,这是一个富文本编辑器,让我们可以尽情编写我们的故事。 相比以上两个组件,这个组件的安装略有些麻烦,依次在cmd中输入以下命令:
npm install ngx-quill@13 --save
npm install quill@1 --save
npm install @types/quill@1 --save
如果都没有报错的话,说明这个组件安装完成了。这里再给出一个ngx-quill的官方npm地址,有问题的话可以参考官方文档:ngx-quill官方文档。 在安装完上面三个组件后,我们就可以开始写我们的第一个angular组件了。
七 编写我们的第一个组件
在angular中,我们使用angular提供的ng工具来生成一切东西,包括组件、模块、服务等。我们这次就来使用ng生成一个组件,作为我们网站的主页面。 在cmd中输入以下命令,让ng来生成一个名为mainlayout的组件作为我们的主页面:
ng g c mainlayout
ng是命令名,g为generate的缩写,c为component的缩写,所以这句命令就告诉angular,我们要使用ng来生成一个名为mainlayout的组件。 如果看到以下画面,说明组件建立成功:  我们在IDE里也可以看到app目录下新增了一个同名目录,下面包含组件四件套的文件:  此外,我们会发现在app.module.ts文件,也会自动将我们的layout组件引入:  一个组件主要包含三部分:html文件,决定了前端要将呈现在浏览器中的样子;css/scss文件,决定了在这个组件中html文件的样式;ts文件,决定了前端页面背后的逻辑,包括不同组件之间的通信、与后端服务器的通信等。我们将分别编写组件的html文件、scss文件和ts文件,从而完成对主页面的开发。
1 编写html文件
由于是主框架,我们决定使用NG-ZORRO中提供的经典上中下布局方式,因此我们需要在项目中引用NzLayoutModule,以便使用NG-ZORRO提供的各种布局元素。 我们修改app.module.ts文件,将NzLayoutModule引;此外,我们在这个页面中还要用到菜单组件,因此这里将NzMenuModule和NzDropDownModule一并引入,分别对应导航菜单和下拉菜单
import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
import { NzMenuModule } from 'ng-zorro-antd/menu';
@NgModule({
declarations: [
AppComponent,
MainlayoutComponent
],
imports: [
NzLayoutModule,
NzDropDownModule,
NzMenuModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
这样,我们就可以在项目全局范围内使用NzLayoutModule中的各种组件了。 我们打开mainlayout/mainlayout.component.html文件,开始构造我们的主页面:
<nz-layout class="layout">
<nz-header>
<div class="logo">
<img src="../../assets/images/tree.svg" width="48" height="48">
</div>
<div *ngIf="isLogin;else elseBlock">
<ul nz-menu [nzTheme]="'dark'" [nzMode]="'horizontal'" style="line-height: 64px;">
<li nz-menu-item>首页</li>
<li nz-menu-item>
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomCenter">
{{currentUser}}
<i nz-icon nzType="down"></i>
</a>
<nz-dropdown-menu #menu="nzDropdownMenu" >
<ul nz-menu nzSelectable>
<li nz-menu-item>书写故事</li>
<li nz-menu-item>个人信息</li>
<li nz-menu-item>退出</li>
</ul>
</nz-dropdown-menu>
</li>
<li nz-menu-item>注册</li>
</ul>
</div>
<ng-template #elseBlock>
<ul nz-menu [nzTheme]="'dark'" [nzMode]="'horizontal'" style="line-height: 64px;">
<li nz-menu-item>首页</li>
<li nz-menu-item>登录</li>
<li nz-menu-item>注册</li>
</ul>
</ng-template>
</nz-header>
<nz-content style="padding:0 50px;">
<div style="padding: 24px;">
<router-outlet></router-outlet>
</div>
</nz-content>
<nz-footer style="text-align: center;">Tree Hole ?2021 CapLiu</nz-footer>
</nz-layout>
整个页面由<nz-layout> 标签包裹,在其中又分为由<nz-header> 定义的头部、<nz-content> 定义的主体和<nz-footer> 定义的脚标三部分。我们把头部定义为展示logo部分和菜单栏,对网站的所有操作均可在菜单栏中进行;而主体部分用于显示不同功能所对应的具体内容,脚标部分则是显示没什么用的版权信息。 下面让我们来看一下这三部分的具体内容。
1.1 <nz-header> 部分
<nz-header> 部分分为两个<div> ,第一个div用于显示logo,我们会将这张图片放在app/assets/images目录下。值得一提的是,angular项目中的图片基本都是svg格式,这种格式是一种矢量图,由XML格式来定义,具有放缩不失真的特性。第一个div没什么好说的,单纯地放一个img标签而已。 而第二个div就复杂的多了,第二个div是我们显示菜单的地方,需要根据用户是否登录来显示不同的菜单,所以这里用到了angular提供的*ngIf语法。 *ngIf语法是angular提供的前端指令之一,用于条件渲染某个元素。其常用语法如下:
1.<div *ngIf="xxx">show</div>
2.<div *ngIf="yyy;else elseblock">show true</div>
<ng-template #elseBlock>show else</ng-template>
第一种语法只有正向条件,即xxx为true时,整个div才会显示出来;第二种语法包括正反两方面,如果yyy是true的话,显示show true;如果yyy不是true的话,就会显示elseblock所指向的<ng-template> 标签中的内容,即show else。xxx和yyy都是在组件的ts文件中定义的变量。关于<ng-template> 的部分,我们在后面做评论组件时还会再详细讲解,这里只要知道它可以这么用就好。 回到我们的组件中。在第二个div中,我们使用了*ngIf=“isLogin;else elseblock”,即如果isLogin这个变量为true的时候,会显示这个div下面的内容,反之则显示底下elseblock的内容。我们在这个div下使用<nz-menu> 放置了三个菜单项<nz-menu-item> ,其中一个菜单项的内容为一个下拉式菜单<nz-dropdown-menu> 。两个菜单项的内容为首页和注册,在将来会为这两个菜单项建立对应的路由;而下拉式菜单在用户登录后会显示当前登录的用户名currentUser。这里的currentUser使用了模板中的插值语法,即用双大括号将变量包起来以显示变量的值。当鼠标移动上去时,下拉菜单会弹出,并提供书写故事、个人信息以及推出的选择,如下图所示: 
如果用户没有登录,即isLogin是false时,我们的菜单会显示下方<ng-template #elseBlock> 中的内容,下拉菜单将会被登录菜单项所取代:  我们网页的header部分就介绍完毕了,本质是一个根据用户登录状态与否而改变的菜单栏。
1.2 <nz-content> 部分
<nz-content> 部分只包含一个div,这个div里存放的是<router-outlet> 元素。<router-outlet> 元素起到一个占位符的作用,意思是通过路由访问的任何组件都将在这个地方显示出来。这个元素会在之后介绍路由的时候再详细介绍。
1.3 <nz-footer> 部分
没啥说的,就是个脚标。 这样,我们就完成了对mainlayout组件的html部分的编写,下面让我们来编写它的ts文件。
2 编写ts文件
我们打开mainlayout.component.ts文件,可以看到以下内容:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-mainlayout',
templateUrl: './mainlayout.component.html',
styleUrls: ['./mainlayout.component.scss']
})
export class MainlayoutComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
@Component修饰器的内容在上一篇博客中已经介绍过了,今天我们来看看MainlayoutComponent类的内容。现在的类只包含两个函数:一个没有任何参数的空的构造函数constructor,和一个不执行任何操作的组件初始化函数ngOnInit。ngOnInit是组件生命周期的钩子函数,会在组件初始化时调用。 由于我们在html文件中使用了isLogin和currentUser这两个变量,因此我们也需要在ts文件中定义它们,否则会编译报错。我们将这两个变量定义为public的,并在构造函数中初始化它们:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-mainlayout',
templateUrl: './mainlayout.component.html',
styleUrls: ['./mainlayout.component.scss']
})
export class MainlayoutComponent implements OnInit {
public isLogin:boolean;
public currentUser:string;
constructor() {
this.isLogin = false;
this.currentUser = '';
}
ngOnInit(): void {
}
}
这里我们将isLogin定义为boolean型变量,将currentUser定义为string型变量,并在构造函数中将isLogin设为false,currentUser设为空。
3 设置scss文件
我们在mainlayout.component.scss设置一下这个组件要用的样式,只有一条:
.logo {
width: 32px;
height: 32px;
margin: 0px 24px 16px 0px;
float: left;
}
最后,我们找一张图扔进assets/images目录下即可。 这样,我们就编写好了我们的主框架mainlayout组件,下面让我们看一下要如何使用这个组件。
4 使用mainlayout组件
我们打开app.component.html,将其所有内容都删掉,换成我们的组件标签:
<app-mainlayout></app-mainlayout>
由于app.component.html是angular工程的根组件,因此我们只要修改这个组件的内容,就可以让我们的组件成为首页了。 再打开根目录下的styles.scss文件,将NG-ZORRO的样式引入。在这个文件里引入的样式会被应用到全局:
@import "~ng-zorro-antd/ng-zorro-antd.min.css";
@import "~ng-zorro-antd/style/index.min.css";
@import "~ng-zorro-antd/button/style/index.min.css";
这时,我们完成了所有的编码工作。在VS Code里的终端中输入npm start命令,稍等一会,然后打开localhost:4200,就可以看到我们的主界面了——一个非常干净,带菜单栏和脚标的页面。  在这篇博客中,我们实现了第一个组件,并将其作为了我们的首页。在下一篇博客中,我们将实现用户注册功能的开发,包括前端组件的编写、服务的使用以及后端tornado的开发,真正进入到全栈的阶段,希望大家继续关注~
|