组件生命周期
环境搭建
安装 Angular CLI
npm install -g @angular/cli
创建工作空间和初始应用
ng new my-app
my-app
就是我们的项目名称
ng new
命令会提示你提供要把哪些特性包含在初始应用中
Angular CLI 会安装必要的 Angular npm 包和其它依赖包。
运行应用
cd my-app
ng serve --open
ng serve
命令会启动开发服务器、监视文件,并在这些文件发生更改时重建应用。
--open
(或者只用 -o
缩写)选项会自动打开你的浏览器,并访问 http://localhost:4200/
。
概述
一个 Angular 的组件包含以下几部分:
一个 HTML 模版文件
一个 TS 组件类
一个样式文件
创建组件
使用 CLI 命令创建组件
ng generate component comp-name
comp-name 是组件名称
默认情况下会创建下面几个文件:
comp-name.component.html
comp-name.component.ts
comp-name.component.css
comp-name.component.spec.ts
手动创建
以组件名为文件夹名称,然后创建上面的三个文件,测试文件可选
对于组件的 ts 文件:
import { Component } from "@angular/core";
@Component({
// 组件名称 css选择器 标签名称
selector: "app-edit-zdt-pen-modal",
// 模版文件使用templateUrl属性
// 模版字符串使用template属性
templateUrl: "./edit-zdt-pen-modal.component.html",
// template: '<h1>Hello World!</h1>',
styleUrls: ["./edit-zdt-pen-modal.component.scss"]
// styles: ['h1 { font-weight: normal; }']
})
export class EditZdtPenModalComponent {}
生命周期和钩子函数
Angular 中每个 component/directive 都有它自己的生命周期。包括创建组件,渲染组件,创建渲染子组件,检测绑定属性变化,回收和从 DOM 中移除。
生命周期有这几种:OnChanges、OnInit、DoCheck、AfterContentInit、AfterContentChecked、AfterViewInit、AfterViewChecked、OnDestroy 钩子函数就是在对应的生命周期前面加上 ng
ngOnChanges
在组件或者指令绑定的 @Input/@Output 属性发生变化的时候调用。需要注意的是如果输入属性绑定的是一个对象,那么只有这个对象的引用发生变化的时候才会调用
ngOnInit
只调用一次,用于初始化组件(对于一些复杂的初始化组件的逻辑应该放在这个里面而不是 constructor)。会在第一个的 ngOnChanges 调用完成之后调用,在这个生命周期中我们已经可以拿到@Input 属性绑定的值了
ngDoCheck
每次变更检测(网络请求、事件、路由变化...)之后都会被调用
状态发生变化,但是 angular 无法捕捉到这个变化的时候也会被调用
注意:这个生命周期会被频繁调用,所以不要写过于复杂的逻辑
ngAfterContentInit
在使用了<ng-content></ng-content>
并且 ng-content 中的内容初始化完成之后调用。我们可以在这个生命周期中访问到通过@ViewChild 选中的子组件
@ContentChild(ChildComponent) contentChild!: ChildComponent;
ngAfterContentChecked
在使用了<ng-content></ng-content>
并且 ng-content 中的内容初始化完成检测后调用,ngDoCheck 调用之后都会触发这个函数。
ngAfterViewInit
在组件以及其子组件初始化完成后会被调用。我们可以在这个生命周期中访问到通过@ViewChild 选中的子组件
@ViewChild(ChildViewComponent) viewChild!: ChildViewComponent;
ngAfterViewChecked
每次检查 compoent 页面或者它的子页面的时候执行,ngDoCheck 调用之后都会触发这个函数。
ngOnDestroy
在组件销毁之前调用,进行一些清理工作
Angular 在调用 AfterView 钩子之前,就已调用完所有的 AfterContent 钩子。 在完成该组件视图的合成之前, Angular 就已经完成了所投影内容的合成工作。 AfterContent... 和 AfterView... 钩子之间有一个小的时间窗,允许你修改宿主视图。
生命周期钩子需要注意的几点:
- constructor vs ngOnInit
在 constructor 里并不是所有数据都已经存在,比如 @Input。所以建议需要使用输入属性的操作都放在 ngOnInit 中。
- ngAfterContentXxx vs ngAfterViewXxx
前者跟对的是 ng-content 中的内容投影。后者针对的是当前组件以及其子组件的视图
- ngOnChanges vs ngDoCheck
ngOnChanges 只有在输入属性的绑定发生变化的时候才会被执行,ngDoCheck 在每次 change detection 的时候都会触发或者是在状态发生变化 Angular 自己又不能捕获时被触发。所以在使用 ngDoCheck 的时候需要非常小心,里面的逻辑尽量精简,因为它会被频繁调用