Angular7 入门总结篇
一、Angular 介绍
- 根据项目数统计
angular(1.x、2.x、4.x、5.x、6.x、7.x)
是现在网上使用量最大的框架 -
Angualr
基于TypeScript
和react
、vue
相比,Angular
更适合中大型企业级项目。
目前 2018 年 11 月 25 日
angular
最新版本angular7.x
。根据官方介绍,Angular
每过几个月 就会更新一个版本。此教程同样适用于后期更新的Angular8.x
、Angular9.x
学习 Angular 必备基础
必备基础:
html
、css
、js
、es6
、Typescript
二、Angular 环境搭建及创建项目
1 环境搭建
1. 安装 nodejs
安装
angular
的计算机上面必须安装最新的nodejs
– 注意安装nodejs
稳定版本
</article>
用
augury
查看component
结构,更方便调试
2.3 目录结构分析
app 目录(重点)
app
目录是我们要编写的代码目录。我们写的代码都是放在这个目录。
一个Angular
程序至少需要一个模块和一个组件。在我们新建项目的时候命令行已经默认生成出来了
-
app.component.ts
:这个文件表示组件, - 组件是
Angular
应用的基本构建模块,可以理解为一段带有业务逻辑和数据的Html
我们来看看app.component.ts
中的代码,并解释下代码的意义
2.4 Angular cli
1. 创建新组件 ng generate component component-name
ng g component components/header
指定生成到哪个目录
该命令会把生成的组件,添加到 src/app/app.module.ts
文件中 @NgModule
的 declarations
列表中声明
三、angular 组件及组件里的模板
3.1 创建 angualr 组件
1. 创建组件
ng g component components/header
2. 使用组件
<app-header></app-header>
3.2 Angular 绑定数据
1. 数据文本绑定
定义数据几种方式
<h1>{{title}}</h1>
2. 绑定HTML
this.h="<h2> 这是一个 h2 用 [innerHTML] 来解析 </h2>"
<div [innerHTML]="h"></div>
3.3 声明属性的几种方式
-
public
共有(默认)可以在类里外使用 -
protected
保护类型 只能在当前类和子类中使用 -
private
私有类型 只能在当期类使用
3.4 绑定属性
用
[]
包裹
<div [id]="id" [title]="msg"> 调试工具看看我的属性 </div>
3.5 数据循环 *ngFor
1. *ngFor 普通循环
export class HomeComponent implements OnInit {arr = [{ name: 'poetries', age: 22}, {name: 'jing' , age: 31}];
constructor() {}
ngOnInit() {}
}
<ul *ngIf="arr.length>0">
<li *ngFor="let item of arr">{{item.name}}- {{item.age}}</li>
</ul>
2. 循环的时候设置 key
<ul>
<li *ngFor="let item of list;let i = index;"> <!-- 把索引 index 赋给 i -->
{{item}} --{{i}}
</li> </ul>
3. template 循环数据
<ul>
<li template="ngFor let item of list">
{{item}}
</li> </ul>
3.6 条件判断 *ngIf
<p *ngIf="list.length > 3"> 这是 ngIF 判断是否显示 </p>
<p template="ngIf list.length > 3"> 这是 ngIF 判断是否显示 </p>
3.7 *ngSwitch
<ul [ngSwitch]="score">
<li *ngSwitchCase="1"> 已支付 </li>
<li *ngSwitchCase="2"> 订单已经确认 </li> <li *ngSwitchCase="3"> 已发货 </li>
<li *ngSwitchDefault> 无效 </li>
</ul>
3.8 执行事件 (click)=”getData()”
<button class="button" (click)="getData()"> 点击按钮触发事件
</button>
<button class="button" (click)="setData()"> 点击按钮设置数据
</button>
getData(){ /* 自定义方法获取数据 */ // 获取
alert(this.msg);
}
setData(){
// 设置值
this.msg='这是设置的值';
}
3.9 表单事件
<input
type="text"
(keyup)="keyUpFn($event)"/>
<input type="text" (keyup)="keyUpFn($event)"/>
keyUpFn(e){console.log(e)
}
3.10 双向数据绑定
<input [(ngModel)]="inputVal">
注意引入:
FormsModule
import {FormsModule} from '@angular/forms'
NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
<!-- 使用 -->
<input type="text" [(ngModel)]="inputValue"/> {{inputValue}}
3. 11 [ngClass]、[ngStyle]
1. [ngClass]:
<div [ngClass]="{'red': true,'blue': false}">
这是一个 div
</div>
public flag=false;
<div [ngClass]="{'red': flag,'blue': !flag}">
这是一个 div </div>
public arr = [1, 3, 4, 5, 6];
<ul>
<li *ngFor="let item of arr, let i = index"> <span [ngClass]="{'red': i==0}">{{item}}</span>
</li> </ul>
2. [ngStyle]:
<div [ngStyle]="{'background-color':'green'}"> 你好 ngStyle</div>
public attr='red';
<div [ngStyle]="{'background-color':attr}"> 你好 ngStyle</div>
3.12 管道
public today=new Date();
<p>{{today | date:'yyyy-MM-dd HH:mm:ss'}}</p>
其他管道
angular
中的管道 (pipe
) 是用来对输入的数据进行处理,如大小写转换、数值和日期格式化等
angular
中的管道(pipe
) 以及自定义管道适用于angular4 angualr5 angualr6 angular7
常用的管道(pipe
)有
1. 大小写转换
<!-- 转换成大写 -->
<p>{{str | uppercase}}</p>
<!-- 转换成小写 -->
<p>{{str | lowercase}}</p>
2. 日期格式转换
<p>
{{today | date:'yyyy-MM-dd HH:mm:ss'}}
</p>
3. 小数位数
接收的参数格式为
{最少整数位数}.{最少小数位数}-{最多小数位数}
<!-- 保留 2~4 位小数 -->
<p>{{p | number:'1.2-4'}}</p>
4. JavaScript 对象序列化
<p>
{{{ name: 'semlinker'} | json }}
</p>
<!-- Output: {"name": "semlinker"} -->
5. slice
<p>{{'semlinker' | slice:0:3}}</p>
<!-- Output: sem -->
6. 管道链
<p>
{{'semlinker' | slice:0:3 | uppercase}}
</p>
<!-- Output: SEM -->
7. 自定义管道
自定义管道的步骤:
- 使用
@Pipe
装饰器定义Pipe
的metadata
信息,如Pipe
的名称 – 即name
属性 - 实现
PipeTransform
接口中定义的transform
方法
7.1 WelcomePipe 定义
import {Pipe, PipeTransform} from '@angular/core';
[@Pipe](/user/Pipe)({name: 'welcome'})
export class WelcomePipe implements PipeTransform {transform(value: string): string {if(!value) return value;
if(typeof value !== 'string') {throw new Error('Invalid pipe argument for WelcomePipe');
}
return "Welcome to" + value;
}
}
7.2 WelcomePipe 使用
<div>
<p ngNonBindable>{{'semlinker' | welcome}}</p>
<p>{{'semlinker' | welcome}}</p> <!-- Output: Welcome to semlinker -->
</div>
四、Angular 中的服务
4.1 服务
定义公共的方法,使得方法在组件之间共享调用
1. 创建服务命令
ng g service my-new-service
# 创建到指定目录下面
ng g service services/storage
2. app.module.ts 里面引入创建的服务
// app.module.ts 里面引入创建的服务
import {StorageService} from './services/storage.service';
// NgModule 里面的 providers 里面依赖注入服务
NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent,
TodolistComponent
], imports: [
BrowserModule,
FormsModule
],
providers: [StorageService],
bootstrap: [AppComponent]
})
export class AppModule { }
3. 使用的页面引入服务,注册服务
import {StorageService} from '../../services/storage.service';
constructor(private storage: StorageService) { }
// 使用
addData(){// alert(this.username);
this.list.push(this.username);
this.storage.set('todolist',this.list);
}
removerData(key){console.log(key);
this.list.splice(key,1);
this.storage.set('todolist',this.list);
}
五、Dom 操作以及 @ViewChild、执行 css3 动画
1. Angular 中的 dom 操作(原生 js)
ngAfterViewInit(){var boxDom:any=document.getElementById('box'); boxDom.style.color='red';
}
2. Angular 中的 dom 操作(ViewChild)
import {Component ,ViewChild,ElementRef} from '@angular/core';
@ViewChild('myattr') myattr: ElementRef;
<div #myattr></div>
ngAfterViewInit(){let attrEl = this.myattr.nativeElement;}
3. 父子组件中通过 ViewChild 调用子组件 的方法
调用子组件给子组件定义一个名称
<app-footer #footerChild></app-footer>
引入
ViewChild
import {Component, OnInit ,ViewChild} from '@angular/core';
ViewChild
和刚才的子组件关联起来
@ViewChild('footerChild') footer
在父组件中调用子组件方法
run(){this.footer.footerRun();
}
六、Angular 父子组件以及组件之间通讯
6.1 父组件给子组件传值 -@input
父组件不仅可以给子组件传递简单的数据,还可把自己的方法以及整个父组件传给子组件
1. 父组件调用子组件的时候传入数据
<app-header [msg]="msg"></app-header>
2. 子组件引入 Input 模块
import {Component, OnInit ,Input} from '@angular/core';
3. 子组件中 @Input 接收父组件传过来的数据
export class HeaderComponent implements OnInit {@Input() msg:string
constructor() {}
ngOnInit() {}
}
4. 子组件中使用父组件的数据
<p>
child works!
{{msg}}
</p>
5. 把整个父组件传给子组件
通过
this
传递整个组件实例
<app-header [home]="this"></app-header>
export class HeaderComponent implements OnInit {@Input() home:any
constructor() {}
ngOnInit() {}
}
执行父组件方法
this.home.xxx()
6.2 子组件通过 @Output 触发父组件的方法(了解)
1. 子组件引入 Output 和 EventEmitter
import {Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';
2. 子组件中实例化 EventEmitter
@Output() private outer=new EventEmitter<string>(); /* 用 EventEmitter 和 output 装饰器配合使用 <string> 指定类型变量 */
3. 子组件通过 EventEmitter 对象 outer 实例广播数据
sendParent(){// alert('zhixing');
this.outer.emit('msg from child')
}
6.4 非父子组件通讯
- 公共的服务
-
Localstorage
(推荐) Cookie
七、Angular 中的生命周期函数
7.1 Angular 中的生命周期函数
官方文档:https://www.angular.cn/guide/lifecycle-hooks
- 生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。
- 当
Angular
使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些 生命周期钩子方法。 - 每个接口都有唯一的一个钩子方法,它们的名字是由接口名再加上
ng
前缀构成的,比如OnInit
接口的钩子方法叫做ngOnInit
.
1. 生命周期钩子分类
基于指令与组件的区别来分类
指令与组件共有的钩子
ngOnChanges
ngOnInit
ngDoCheck
ngOnDestroy
组件特有的钩子
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
2. 生命周期钩子的作用及调用顺序
1、ngOnChanges
– 当数据绑定输入属性的值发生变化时调用
2、ngOnInit
– 在第一次 ngOnChanges
后调用
3、ngDoCheck
– 自定义的方法,用于检测和处理值的改变
4、ngAfterContentInit
– 在组件内容初始化之后调用
5、ngAfterContentChecked
– 组件每次检查内容时调用
6、ngAfterViewInit
– 组件相应的视图初始化之后调用
7、ngAfterViewChecked
– 组件每次检查视图时调用
8、ngOnDestroy
– 指令销毁前调用
3. 首次加载生命周期顺序
export class LifecircleComponent {constructor() {console.log('00 构造函数执行了 --- 除了使用简单的值对局部变量进行初始化之外,什么都不应该做')
}
ngOnChanges() {console.log('01ngOnChages 执行了 --- 当被绑定的输入属性的值发生变化时调用(父子组件传值的时候会触发)');
}
ngOnInit() {console.log('02ngOnInit 执行了 --- 请求数据一般放在这个里面');
}
ngDoCheck() {console.log('03ngDoCheck 执行了 --- 检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应');
}
ngAfterContentInit() {console.log('04ngAfterContentInit 执行了 --- 当把内容投影进组件之后调用');
}
ngAfterContentChecked() {console.log('05ngAfterContentChecked 执行了 --- 每次完成被投影组件内容的变更检测之后调用');
}
ngAfterViewInit() : void {console.log('06 ngAfterViewInit 执行了 ---- 初始化完组件视图及其子视图之后调用(dom 操作放在这个里面)');
}
ngAfterViewChecked() {console.log('07ngAfterViewChecked 执行了 ---- 每次做完组件视图和子视图的变更检测之后调用');
}
ngOnDestroy() {console.log('08ngOnDestroy 执行了····');
}
// 自定义方法
changeMsg() {this.msg = "数据改变了";}
}
7.2.7 ngAfterViewInit()– 掌握
初始化完组件视图及其子视图之后调用。第一 次
ngAfterContentChecked()
之后调用,只调用一次。在这里可以操作DOM
7.2.9 ngOnDestroy()– 掌握
当
Angular
每次销毁指令 / 组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄 漏。在Angular
销毁指令 / 组件之前调用。比如:移除事件监听、清除定时器、退订Observable
等。
@Directive({selector: '[destroyDirective]'
})
export class OnDestroyDirective implements OnDestroy {
sayHello: number;
constructor() {this.sayHiya = window.setInterval(() => console.log('hello'), 1000);
}
ngOnDestroy() {window.clearInterval(this.sayHiya);
}
}
八、Rxjs 异步数据流编程
8.1 Rxjs 介绍
-
RxJS
是一种针对异步数据流编程工具,或者叫响应式扩展编程; 可不管如何解释 RxJS 其目 标就是异步编程,Angular
引入RxJS
为了就是让异步可控、更简单。 -
RxJS
里面提供了很多模块。这里我们主要给大家讲RxJS
里面最常用的Observable
和fromEvent
目前常见的异步编程的几种方法:
- 回调函数
- 事件监听 / 发布订阅
Promise
Rxjs
8.3 Rxjs unsubscribe 取消订阅
Promise
的创建之后,动作是无法撤回的。Observable
不一样,动作可以通过unsbscribe()
方法中途撤回,而且Observable
在内部做了智能的处理.
Promise 创建之后动作无法撤回
九、路由
// 引入组件
import {HomeComponent} from './home/home.component';
import {NewsComponent} from './news/news.component';
import {NewscontentComponent} from './newscontent/newscontent.component';
// 配置路由
const routes: Routes = [{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path: 'newscontent/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
} ];