代码已提交至github
做好了之前的准备工作,终于可以着手优化界面了。
优化界面的组件UI库,我用的是Bootstrap4.0。原因有二:一方面是因为不用npm install,只用导入镜像链接实在是方便;另一方面,据说写Bootstrap就是写Angular的同一帮人(官方文档上用的就是Bootstrap)。
引入bootstrap
和Antd不同,Bootstrap的使用不用npm install –save进行库的依赖安装(当然其实这样用也可以),只要联网就可以运行。当然缺点也是很明显的,必须联网才能运行。
现在可以进入src/public/index.html里,放开之前注释掉的引用了。
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
Bootstrap的开发者很贴心的准备了一些样例供人使用,绝对的业界良心。
我模仿的是这一个主题:
下载对应的example打开,可以看到这个页面的样式是由头、身、尾组成的。
<nav class="navbar navbar-toggleable-md navbar-inverse fixed-top bg-inverse">
导航栏
</nav>
<div class="jumbotron">
内容
</div>
<div class="container">
内容
</div>
<hr>
<footer>
页脚
</footer>
导航栏和页脚是每个页面都有的,所以最好需要添加到主页面的View——app.component.html里面。无论主页还是详情页,都是通过app.component.html里的router-outlet展示。这样在以后的页面中,都可以公共的享受页眉和页脚了。
给整个项目增加导航栏和页脚
修改app.component.html,先把body页眉中的代码复制进来:
<!-- 最外层的**nav**标签,表明这是一个导航栏(navBar) -->
<nav class="navbar navbar-toggleable-md navbar-inverse fixed-top bg-inverse">
<!-- 导航栏中有一个button来控制菜单的隐藏和显示(toggle)-->
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<!-- 按钮的图标-->
<span class="navbar-toggler-icon"></span>
</button>
<!-- 超链接控制导航栏的名称和跳转-->
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<!-- 导航栏中包括的导航菜单-->
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
<!-- 这个菜单和别的菜单不一样,这个有下拉列表-->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<!-- 导航栏中的表单-->
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
看起来比较乱,其实结构就像积木一样清晰,跟着结构增加和删除就可以得到想要的效果。
首先navbar是需要的,但是我不希望他固定在最开头,去掉fixed-top。同时因为海牛高达是蓝色的,所以希望能把navbar的颜色也换一下。navbar的名字也更换一下,form表单不需要。菜单栏只保留必要的就可以,我保留了2个,一个是主页,一个指向我的csdn。最后加上页脚,完成。
app.component.html
<nav class="navbar navbar-toggleable-md navbar-inverse bg-primary">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">大天使号</a>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://blog.youkuaiyun.com/catwindboy/">About</a>
</li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
<hr>
<footer>
<p>© 龙骑将杨影枫</p>
</footer>
有点模样了呢:
继续再接再厉的修改主页。
修改主页
修改gundam-host.component.html文件,加上一段项目说明和git地址。
<div class="jumbotron">
<div class="container">
<h1 class="display-5">Hello, Meister!</h1>
<p>你好,我是龙骑将杨影枫,欢迎来到我的城堡。</p>
<p>这是端午节假期在家里对着angular官网教程自己撸的一个小东西,用到了angular中compoent和service,以及http模块进行网络请求。</p>
<p><a class="btn btn-primary btn-lg" href="https://github.com/stormrabbit/gundam-meister" role="button">GitHub »</a></p>
</div>
</div>
然后处理首页展示的高达机体,目前我们想显示3个,所以要修改controller(也就是gundam-host.component.ts文件中的class)。
this.gundamService.getGundams().then(gundams => this.gundams = gundams.slice(0, 3)); // 让主页只显示3个
但是希望这3个能好好显示,所以还要扩展gundam.ts的属性。
export class Gundam {
id: number; // id
name: string; // 姓名
type: string; // 类型
armor: string; // 装备
weapon: string; // 武器
status: number; // 状态
guestNum: number; // 任务次数
imgUrl: string; // 图片
describe: string; // 描述
}
修改主页gundam-host.component.html,增加一段项目说明并选择展示三个高达。
<div class="jumbotron">
<div class="container">
<h1 class="display-5">Hello, Meister!</h1>
<p>你好,我是龙骑将杨影枫,欢迎来到我的城堡。</p>
<p>这是端午节假期在家里对着angular官网教程自己撸的一个小东西,用到了angular中compoent和service,以及http模块进行网络请求。</p>
<p><a class="btn btn-primary btn-lg" href="https://github.com/stormrabbit/gundam-meister" role="button">GitHub »</a></p>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-4" *ngFor="let gundam of gundams">
<my-host-item [gundam]="gundam">
</my-host-item>
</div>
</div>
</div>
PS:
<div class="container">
<div class="row">
<div class="col-md-4"
这样的写法,是Bootstrap对于栅格化item显示的解决办法,代表在一行内显示3个div。Bootstrap把一行分为12个格子,然后用col-x(x代表占几个格子)来在一行内显示不同div的宽度。class=”container”表示需要栅格化显示,col-x可以为任意不大于12的整数,也整个class=”row”的div内所有div的col-x相加不得大于12。
修改gundam-host-item.component.html
<h2>{{gundam.name}}</h2>
<p>{{gundam.describe}}</p>
<p><a class="btn btn-secondary" [routerLink]="['/detail', gundam.id]" role="button">查看详细资料»</a></p>
界面显示:
我把跳转的连接从host移动到了host-item,是出于“让模块做自己该做的事情”这条原则的考虑。主页关心的是显示3个高达item,别的不关心;而item关心的是如何应对用户对本item的操作和自身的界面,如何被显示也不关心。
还是有点不满意,希望显示详细资料这个按钮可以偏右,但是Bootstrap没有提供这个样式。
没有枪没有炮,我们自己造。
具体来说,就是scss。
引入自定义的scss
组件内引入scss,还是要依靠组件注解@Component中的属性stylesUrl。
@Component的styleUrl属性接受的是一个字符串数组,字符串引入的scss文件地址。如果样式比较简单的话也可以用styles属性自己写,接受的是一个反引号数组,但是我个人不太推荐。
让上帝的归上帝凯撒的归凯撒吧,controller就是controller,不要有别的东西。
在\src\app\component\host-item\html的文件下新建gundam-host-item.component.scss文件并增加一些scss样式:
.hostItem{
padding: 10px;
}
.viewDetail{
float: right;
}
引入到gundam-host-item.component.ts文件里使用:
import { Component, Input } from '@angular/core';
import { Gundam } from './../../model/gundam';
@Component({
selector: 'my-host-item',
templateUrl: './html/gundam-host-item.component.html',
styleUrls: ['./html/gundam-host-item.component.scss']
})
export class GundamHostItemComponent {
@Input() gundam: Gundam;
}
修改相应的gundam-host-item.component.html文件,给div加上class
<div class="hostItem">
<h2>{{gundam.name}}</h2>
<p>{{gundam.describe}}</p>
<p class="viewDetail"><a class="btn btn-secondary" [routerLink]="['/detail', gundam.id]" role="button">查看详细资料»</a></p>
</div>
现在看看效果,就有点意思了:
修改detail页面
用同样的方法,修改一下详情页面,使其能展示机体更多的参数。
修改gundam-detail.component.ts (其实没做啥,只是引入scss)
import {
Component,
OnInit
} from '@angular/core';
import {
Gundam
} from '../../model/gundam';
import {
ActivatedRoute,
Params
} from '@angular/router';
import { GundamService } from '../../service/gundam.service';
import 'rxjs/add/operator/switchMap';
@Component({
templateUrl: './html/gundam-detail.component.html',
styleUrls: ['./html/gundam-detail.component.scss']
})
export class GundamDetailComponent implements OnInit {
selectedGundam: Gundam;
gundamStr: string;
gundamId: number;
constructor(
private route: ActivatedRoute,
private gundamService: GundamService,
) {}
ngOnInit(): void {
this.route.params.switchMap((params: Params) => this.gundamService.getGundamById(+params['id']))
.subscribe( gundam => this.selectedGundam = gundam );
}
}
增加gundam-detail.component.scss文件:
.myBody{
padding: 5px;
}
.formItem{
margin: 10px;
}
.formItem div{
border: 1px solid #f9f9f9;
}
最后修改V,gundam-detail.component.html
<div *ngIf="selectedGundam" class="myBody">
<div>
<img src="{{selectedGundam.imgUrl}}" alt="{{selectedGundam.name}}" style="width: 100%">
</div>
<div class="container formItem" style="text-align: left;padding: 5px">
<div class="row">
<div class="col">
名称
</div>
<div class="col">
{{selectedGundam.name}}
</div>
</div>
<div class="row">
<div class="col">
类型
</div>
<div class="col">
{{selectedGundam.type}}
</div>
</div>
<div class="row">
<div class="col">
装备
</div>
<div class="col">
{{selectedGundam.armor}}
</div>
</div>
<div class="row">
<div class="col">
武器
</div>
<div class="col">
{{selectedGundam.weapon}}
</div>
</div>
<div class="row">
<div class="col">
<p>{{selectedGundam.describe}}</p>
</div>
</div>
</div>
</div>
现在刷新一下详情页:
最后,用webpack打包。将打包后的文件放到server的assets目录下,重启服务器。
访问
http://localhost:4000/
点击海牛高达:
本文记录了在Angular4项目中使用Bootstrap4进行界面优化的过程,包括引入Bootstrap、添加导航栏和页脚、修改主页及detail页面。通过Bootstrap的栅格系统实现布局,并自定义scss样式提升用户体验。
1104

被折叠的 条评论
为什么被折叠?



