提前体验一下圣诞氛围的【前篇】
我们P&D的圣诞节倒数日历终于到了第19天。因为我们只是一个IT开发和运维的学生团体,所以现在是时候发布一些正经的编程文章了吧?因此,我们希望能够通过IT的力量来感受圣诞的氛围!
操作背景。
- macOS Mojave 10.14.2
前提条件 tí
-
- nodeとnpmはインストール済みであることとします。
- 長めの記事になりそうなので、時間に余裕のある人を対象にしておきます。
Angular的环境配置
如果您一边阅读Angular的日文文档,一边实践,我相信您肯定会很顺利地前进。
在这里,作为一个绝对不想弄乱全局环境的人,我会按照个人的方法进行环境搭建。
首先,我会进入工作目录,然后从npm init开始进行操作。
$ mkdir Angular
$ cd Angular
$ npm init
接下来是安装Angular。根据Angular的日文文档中所述,应使用npm install -g @angular/cli进行全局安装。然而,这样就会导致全局安装,所以这次我们故意选择本地环境安装。
$ npm i -D @angular/cli
$ npx ng --version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 7.1.3
Node: 11.2.0
OS: darwin x64
Angular: undefined
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.11.3
@angular-devkit/core 7.1.3
@angular-devkit/schematics 7.1.3
@angular/cli 7.1.3
@schematics/angular 7.1.3
@schematics/update 0.11.3
rxjs 6.3.3
typescript 3.1.6
如果出现这样的输出,我认为没有问题。
需要注意的是,第一条命令是npm …,而第二条命令是npx …。这是一种调用本地环境中安装的CLI命令的方法,记住它会很方便。
制作之物 (zhì zuò zhī wù)
既然已经来了,我打算在以下条件的基础上完成。
-
- PCでもスマホでも閲覧可能なもの
-
- リアクティブもつけてみたい!
-
- 当然クリスマス気分になれるもの
- サンタさんからたくさんのプレゼントをもらいたい!
最後のとかただの願望でしかありません…これでも大学生ですよ…
とりあえずこのような感じのものを目標にして作り進めていきます。

编码
设计
让我们首先考虑需要哪些组件。
尽管在组件的分割方法上每个人可能都有不同的流派,但这次我们将大致按以下方式进行划分。
-
- ツリー(一応こいつがメイン)
-
- プレゼント(背景とか)
- アクションボタン
我相信除了这些之外,我们还会随时创建更多的组件,但大体上这三个组件将构成基础部分的组件(计划中)。
创建应用程序
我会在命令行界面快速创建应用程序的框架。
$ npx ng new merry-christmas
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use?
CSS
❯ SCSS [ http://sass-lang.com ]
SASS [ http://sass-lang.com ]
LESS [ http://lesscss.org ]
Stylus [ http://stylus-lang.com ]
...省略...
Successfully initialized git.
执行命令时,可能会询问“是否要添加Angular路由?”我认为这次不需要路由,但可能会有使用的可能性,所以先选择“y”。
下一个问题是选择样式表的编写语言。我选择了SCSS,但这里用自己最熟悉的都可以,没有问题。
现在模板已经完成了,我们来启动本地服务器试试看。
$ ng s
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
Date: 2018-12-16T13:29:44.974Z
Time: 6957ms
chunk {main} main.js, main.js.map (main) 11.6 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 223 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 16.7 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.67 MB [initial] [rendered]
ℹ 「wdm」: Compiled successfully.
如果在浏览器中打开 localhost:4200,出现如下所示的画面,那么准备工作已经完成了。

创建组件
暂时快速建立基础部分。由于所需组件是之前提到的三个,所以我们会随意命名并创建。
在先解释一下命令,下面输入的命令使用的是ng generate component <组件名称>的简写形式,即ng g c <组件名称>。
$ ng g c tree
CREATE src/app/tree/tree.component.scss (0 bytes)
CREATE src/app/tree/tree.component.html (23 bytes)
CREATE src/app/tree/tree.component.spec.ts (614 bytes)
CREATE src/app/tree/tree.component.ts (262 bytes)
UPDATE src/app/app.module.ts (467 bytes)
$ ng g c presents
CREATE src/app/presents/presents.component.scss (0 bytes)
CREATE src/app/presents/presents.component.html (27 bytes)
CREATE src/app/presents/presents.component.spec.ts (642 bytes)
CREATE src/app/presents/presents.component.ts (278 bytes)
UPDATE src/app/app.module.ts (557 bytes)
$ ng g c actions
CREATE src/app/actions/actions.component.scss (0 bytes)
CREATE src/app/actions/actions.component.html (26 bytes)
CREATE src/app/actions/actions.component.spec.ts (635 bytes)
CREATE src/app/actions/actions.component.ts (274 bytes)
UPDATE src/app/app.module.ts (643 bytes)
我可以使用这个组件来创建。
现在终于可以开始编码了!
引入图书馆
这次我们会引入一些材料。有篇很棒的文章,所以我们会参考它,同时阅读官方网站,然后继续进行。
参考网站
– Angular7 + AngularMaterial环境配置
– Angular Material
$ npm install --save @angular/material @angular/cdk @angular/animations
听说有一个可以很好地帮助我进行引入的命令,所以我打算试一试。
$ ng add @angular/material
Installing packages for tooling via npm.
? Choose a prebuilt theme name, or "custom" for a custom theme: (Use arrow keys)
Indigo/Pink [ Preview: https://material.angular.io?theme=indigo-pink ]
Deep Purple/Amber [ Preview: https://material.angular.io?theme=deeppurple-amber ]
Pink/Blue Grey [ Preview: https://material.angular.io?theme=pink-bluegrey ]
Purple/Green [ Preview: https://material.angular.io?theme=purple-green ]
❯ Custom
$ ng add @angular/material
Installing packages for tooling via npm.
? Choose a prebuilt theme name, or "custom" for a custom theme: Custom
? Set up HammerJS for gesture recognition? Yes
? Set up browser animations for Angular Material? Yes
UPDATE package.json (1404 bytes)
audited 40183 packages in 7.028s
found 0 vulnerabilities
UPDATE src/main.ts (391 bytes)
UPDATE src/app/app.module.ts (752 bytes)
UPDATE src/styles.scss (1514 bytes)
UPDATE src/index.html (482 bytes)
在引入Material Design时,由于需要自行导入所需的模块,所以我将参考之前的文章来进行导入。
– 第六步:创建用于Material的模块。
在公式的示例源代码中创建一个类似的材料模块。
终端:
$ ng generate module shared/material –flat执行后将创建src/app/shared/material.module.ts。
编辑创建的模块如下所示。
(全部)src/app/shared/material.module.tsmaterial.module.ts
import {DragDropModule} from ‘@angular/cdk/drag-drop’;
import {ScrollingModule} from ‘@angular/cdk/scrolling’;
import {CdkTableModule} from ‘@angular/cdk/table’;
import {CdkTreeModule} from ‘@angular/cdk/tree’;
import {NgModule} from ‘@angular/core’;
import {
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatStepperModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
} from ‘@angular/material’;@NgModule({
exports: [
CdkTableModule,
CdkTreeModule,
DragDropModule,
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
ScrollingModule,
]
})
export class MaterialModule {}版权所有 2018 Google Inc.
本源代码的使用受MIT样式许可证的限制,该许可证可以在http://angular.io/license的LICENSE文件中找到。app.module.ts
import { MaterialModule } from ‘./shared/material.module’;
省略部分@NgModule({
省略部分
imports: [
MaterialModule
省略部分
]
})・app.module.ts(全部)
app.module.ts
import { BrowserModule } from ‘@angular/platform-browser’;
import { NgModule } from ‘@angular/core’;import { AppRoutingModule } from ‘./app-routing.module’;
import { AppComponent } from ‘./app.component’;
import { TreeComponent } from ‘./tree/tree.component’;
import { PresentsComponent } from ‘./presents/presents.component’;
import { ActionsComponent } from ‘./actions/actions.component’;
import { BrowserAnimationsModule } from ‘@angular/platform-browser/animations’;
import { MaterialModule } from ‘./shared/material.module’;@NgModule({
declarations: [
AppComponent,
TreeComponent,
PresentsComponent,
ActionsComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
我想这样应该已经成功引入了材料设计!
HTML的原意是超文本标记语言。
暂时先不用考虑CSS,我们赶紧填写所需的内容吧。
<h1><span>Merry</span> <span>Christmas</span></h1>
<app-tree></app-tree>
<app-presents></app-presents>
<app-actions></app-actions>
<router-outlet></router-outlet>
<img alt="tree" src="../../assets/christmastree_nude.png">
<img alt="present" src="../../assets/christmas_presents.png">
<button mat-raised-button>ツリーにかざる</button>
<button mat-raised-button>プレゼントを願う</button>
让我们在浏览器中确认当前状态。
$ ng s

嗯,感觉还可以吧。不过按钮部分确实做得很精致!(^_^)
我会从这里开始美化外观。
CSS/SCSS 可選擇使用原生中文表達為「層疊樣式表/可擴展樣式表」。
那么,让我们开始美化刚刚准备的HTML页面吧。
首先,我们进行样式的初始化。
实际上,对于样式的初始化,最好是准备一个单独的SCSS文件以便更易理解。但是,由于我们只是暂时将所有元素的边距和填充设为0,所以我们将其直接写在style.scss的末尾。
...省略...
* {
margin: 0;
padding: 0;
}
首先,我们将调整作为整体核心的tree.component。
<div class="tree">
<img alt="tree" src="../../assets/christmastree_nude.png">
</div>
.tree {
text-align: center;
height: 70vh;
img{
height: 100%;
object-fit: contain;
}
}
总之,大致就是这样吧…
下面是一种中文翻译:
接下来,在app.component中写入所需的SCSS。
虽然只有一个h1标签,但我们可以通过更改字体和字号、居中对齐以及适当调整角度来达到期望的效果。
同时,我们也要考虑响应式设计。
h1{
font-family: 'Aguafina Script', cursive;
font-size: 72px;
text-align: center;
padding-top: 30px;
margin-left: 5vw;
@media screen and (max-width:479px) {
margin-top: 20px;
font-size: 48px;
}
span{
position: relative;
display: inline-block;
padding: 0 5vw;
transform: rotate(-10deg);
@media screen and (max-width:479px) {
padding: 0 2vw;
}
}
}
由于使用了Google字体,所以我会在index.html的标签内准备一个链接。
参考:Google字体
<head>
...省略...
<link href="https://fonts.googleapis.com/css?family=Aguafina+Script" rel="stylesheet">
</head>
<!doctype html>
我会像这样调整剩下的组件,让它们看起来好一点。
<div class="present">
<img alt="present" src="../../assets/christmas_presents.png">
</div>
.present{
position: absolute;
bottom: 20vh;
right: 10vw;
height: 20vh;
img{
height: 100%;
object-fit: contain;
}
}
<ul class="action-button">
<li class="action-button__decoration"><button mat-raised-button>ツリーにかざる</button></li>
<li class="action-button__present"><button mat-raised-button>プレゼントを願う</button></li>
</ul>
ul{
list-style: none;
text-align: center;
margin-top: 10px;
margin-left: 2.5vw;
height: 32px;
@media screen and (max-width:479px) {
margin-top: 10px;
height: 24px;
}
li{
display: inline-block;
height: 100%;
margin: 0 20px;
@media screen and (max-width:479px) {
margin-bottom: 20px;
}
button{
font-size: 27px;
border: 3px solid #33CBEC;
box-sizing: border-box;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
border-radius: 27px;
}
}
}
将模拟数据导入系统
在完成了底座后,我们会制作模拟数据并进行圣诞风格的装饰!
制作数据模板
$ ng g class present
CREATE src/app/present.ts (25 bytes)
$ ng g class decorates
CREATE src/app/decorates.ts (27 bytes)
请按照以下方式编辑每个文件的内容。
export class Present {
id: number;
name: string;
src: string;
}
export class Decorate {
id:number;
name: string;
src: string;
}
制作模拟数据
根据这些材料,我会制作适量的模型。
import { Present } from "./present";
export const PRESENTS: Present[] = [
{id: 1, name: "green_present", src: "christmas_mark2_present.png"},
{id: 2, name: "many_present", src: "christmas_presents.png"},
{id: 3, name: "socks_present", src: "christmas_socks.png"},
];
import { Decorate } from "./decorate";
export const DECORATES:Decorate[] = [
{id: 1, name: "red ball", src: "christmas_kugel01_red.png"},
{id: 2, name: "pink ball", src: "christmas_kugel02_pink.png"},
{id: 3, name: "blue ball", src: "christmas_kugel06_blue.png"},
{id: 4, name: "lime ball", src: "christmas_kugel08_lime.png"},
{id: 5, name: "yellow ball", src: "christmas_kugel10_yellow.png"},
{id: 6, name: "santa", src: "christmas_ornament01_santa.png"},
{id: 7, name: "snowman", src: "christmas_ornament03_snowman.png"},
{id: 8, name: "snowman_hat", src: "christmas_ornament04_snowman.png"},
{id: 9, name: "present red", src: "christmas_ornament05_present.png"},
{id: 10, name: "present green", src: "christmas_ornament06_present.png"},
{id: 11, name: "sock", src: "christmas_ornament08_sock.png"},
{id: 12, name: "double bells", src: "christmas_ornament09_bells.png"},
{id: 13, name: "star", src: "christmas_ornament11_star.png"},
{id: 14, name: "candy", src: "christmas_ornament12_candy.png"},
{id: 15, name: "matsubokkuri", src: "christmas_ornament15_matsubokkuri.png"},
{id: 16, name: "candy", src: "christmas_ornament12_candy.png"},
];
数据输入
首先我们尝试修改礼物组件。
在HTML/CSS中进行一些修改,并将数据注入进去。
<div class="present" *ngFor="let present of presents">
<div class="present__{{present.id}}">
<img alt="{{present.name}}" src="../../assets/{{present.src}}">
</div>
</div>
.present{
@media screen and (max-width:480px) {
display: none;
}
&__1{
position: absolute;
top: 25vh;
right: 20vw;
height: 20vh;
}
&__2{
position: absolute;
bottom: 27vh;
left: 12vw;
height: 30vh;
transform: scale(-1, 1);
}
&__3{
position: absolute;
bottom: 20vh;
right: 10vw;
height: 20vh;
}
img{
height: 100%;
object-fit: contain;
}
}
import { Component, OnInit } from '@angular/core';
import { PRESENTS } from '../mock-presents';
import { Present } from '../present';
@Component({
selector: 'app-presents',
templateUrl: './presents.component.html',
styleUrls: ['./presents.component.scss']
})
export class PresentsComponent implements OnInit {
presents: Present[] = PRESENTS;
constructor() { }
ngOnInit() {
}
}
只需要一个选项,原文翻译成中文:
只需按下按钮,并妥善处理,就能够完成了!…因为太长了,所以这篇文章分成了两部分。 (>人<;)
请留意下期作品稍后发表m(_ _)m
完成形 – 完成的形态 de

辛苦啦!
一点闲聊
如果尺寸大致如此,那么无需思考,直接制作组件并快速编写代码会更有趣呢,哈哈。
如果有心情的话,也可以随时体验一下圣诞节的氛围,不是吗(・∀・)
在制作过程中我注意到,原来即使在本地安装了CLI,也可以不用npx等命令来使用!我以为是Angular给准备了脚本,但实际上只是Angular提供了脚本而已…
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}
Angular先生真是优秀的到不行啊(≧∀≦)
以下是本次的源代码
请参考下列资料。
参考资料:
Angular7 + AngularMaterial环境搭建
Angular日本语文档
Angular Material