Angular-07:组件生命周期

三个阶段:

  • ① 挂载阶段
    • 1.1 constructor
    • 1.2 ngOnInit
  • ② 更新阶段
    • 2.1 ngOnChanges
    • 2.2 ngAfterViewInit
    • 2.3 ngAfterContentInit
    • 2.4 ngDoCheck
  • ③ 卸载阶段
    • 3.1 onOnDestroy
  • ④ 在组件中添加所有方法并打印

该表按照执行顺序编写

编号 函数名 实现名 说明
1 constructor constructor 接收服务实例化对象
2 ngOnChanges OnChanges 当输入属性值发生变化时执行
3 ngOnInit OnInit 在首次接收到输入属性值后执行
4 ngDoCheck DoCheck 主要用于调试,每次变化检测发生时调用
5 ngAfterContentInit AfterContentInit 当内容投影初始渲染完成后调用
6 ngAfterContentChecked AfterContentChecked 内容投影更新完成后执行
7 ngAfterViewInit AfterViewInit 当组件视图渲染完成后调用
8 ngAfterViewChecked AfterViewChecked 组件视图更新完成后执行
9 ngOnDestroy OnDestroy 组件被销毁之前调用

① 挂载阶段

该阶段生命周期函数只执行一次,数据更新时不再执行。

1.1 constructor

  1. 不是组件生命周期函数,是组件类的构造函数,但是他属于挂载阶段
  2. 建议只接收服务实例化对象,不要干其他的事
  3. angular实例化组件类时执行,可以用来接收angular注入的服务实例对象。

例: 创建一个服务“TestService”, 在组件中注入服务并在constructor中打印查看结果

TestService:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class TestService {

  testTip = "test,来自服务的消息";

  constructor() { }

}
export class OtherComponent implements OnInit{

  constructor(
    private TestService: TestService
  ) {
    console.log("this.TestService--", this.TestService.testTip);  // test,来自服务的消息

  }
}

结果:
Angular-07:组件生命周期_第1张图片


1.2 ngOnInit

在首次接收到输入属性后执行,也用来做初始化任务执行

例: 创建一个子组件,在父组件中传递给子组件一个输入值,在子组件中打印查看结果。

在父组件中的子组件标签定义好属性



<app-son [sonName]="'王二小'">app-son>

子组件接收该属性值并打印

// 子组件类
export class SonComponent implements OnInit {

  @Input() sonName: string = '';

  constructor() { }

  ngOnInit() {
    console.log("sonName", this.sonName);   // 王二小
  }

}

结果:
Angular-07:组件生命周期_第2张图片


② 更新阶段

2.1 ngOnChanges

  1. 输入属性发生变化时执行,初始设置时也会执行一次。响应组件输入值发生变化时出发。(顺序优先于ngOnInit)
  2. 不论有多少个输入属性同时变化,该钩子只会执行一次,变化的值会同时存储在参数中。(多个输入属性一起传递,钩子函数会同时处理)
  3. 参数的类型为SimpleChanges,子属性类型为SimpleChange。
  4. 对于基本数据类型来说,只要值发生改变就可以被该函数检测到。
  5. 对于引用数据类型来说,可以检测从一个对象变成另一个对象(整个对象重新赋值,引用地址发生了变化),但是检测不到同一个对象中属性值的变化(某个属性值被改变),但是不影响组件模板更新数据。(钩子函数捕捉不到改变,但是在组件模板中会变化)

例1:基本数据类型值变化

  1. 给子组件传递一个基本数据类型属性 sonName,值为:王二小。
  2. 定义一个按钮,点击按钮时将该值改为:李四。

<app-son [sonName]="sonName">app-son>
<button (click)="changeName()">换个名字button>
// 父组件类

  sonName: string = '王二小';

  changeName() {
    this.sonName = "李四";
  }

在子组件类中接收该值,并在ngOnChanges方法中添加打印,查看该值的变化

// 子组件类

  @Input() sonName: string;

  ngOnChanges(changes: SimpleChanges): void {
    console.log("changes", changes);
    console.log("sonName", this.sonName);
  }
  1. 基本数据类型的值改变可以在该方法中被检测到
  2. SimpleChanges对象:包含当前值和变化前的值。输入属性值发生变化时触发。
    Angular-07:组件生命周期_第3张图片

例2:引用数据类型对象属性变化

  1. 给子组件传递一个对象 sonInfo,值为:{ name: “王二小”, age: 18 }。
  2. 定义一个按钮,点击按钮时将该对象的属性改变。


<app-son [sonInfo]="sonInfo">app-son>
<button (click)="changeInfo()">换个信息button>

在父组件类中改变该对象的属性

// 父组件类

  sonInfo = { name: "王二小", age: 18 };

  changeInfo() {
    this.sonInfo.name = "李四";
    this.sonInfo.age = 3;
  }
  1. 在子组件类中接收该对象sonInfo,并在ngOnChanges中添加打印
// 子组件类

 @Input() sonInfo: Object;

  ngOnChanges(changes: SimpleChanges): void {
    console.log("changes", changes);
    console.log("sonInfo", this.sonInfo);
  }

在子组件模板中将该对象显示



<p>{{sonInfo | json}}p>

最终结果:

  1. 初始化的时候ngOnChanges方法会打印接收的input对象。
  2. 在父组件中点击按钮改变对象属性时,该对象传递到子组件中。
  3. 由于值改变了对象属性,ngOnChanges方法无法检测到该对象的变化,不会输出打印。
  4. 但是在子组件模板中可以看到,该对象已经由最初的 “王二小” 变为了 “李四” 。Angular-07:组件生命周期_第4张图片

例3:引用数据类型引用地址变化

  1. 同例2逻辑,这次在父组件传递给子组件值时改变对象赋值方式。
  2. 在点击按钮时,在父组件中对象重新赋值。(改变对象的引用地址)
// 父组件组件类
sonInfo = { name: "王二小", age: 18 };

  changeInfo() {
    this.sonInfo = { name: "李四", age: 3 };
  }

最终结果:
每次点击按钮,ngOnChanges都会检测到该对象的变化
Angular-07:组件生命周期_第5张图片


2.2 ngAfterViewInit

  1. 组件视图渲染完成后调用。
  2. angular创建完成组件视图及其子视图之后。

2.3 ngAfterContentInit

  1. 当内容投影初始渲染完成调用。
  2. 组件中使用了将内容嵌入组件视图后会调用,在第一次ngDoCheck执行后调用,且只执行一次。

2.4 ngDoCheck

  1. 用于变化检测,该钩子方法会在每次变化检测发生时调用。
  2. 不管数据值是否发生了变化,都会被调用,该钩子方法需慎用。该方法内不能写复杂代码,会影响性能。
  3. 例如鼠标移动事件,变化检测会频繁触发,该钩子方法会频繁调用。
  4. ngDoCheck和ngOnChange不建议同时使用。

③ 卸载阶段

3.1 onOnDestroy

  1. 什么是卸载?
    组件所对应的dom元素被移除就是卸载。避免发生内存泄漏等问题。
  2. 当组件被销毁之前调用,用于清理操作。
  3. 一个经典应用场景,从a页面b页面时,a页面所对应的组件就会被卸载掉。
  4. 需要在该函数内处理:已订阅的观察者事件清理,定时器清理,绑定的dom清理(一些不会被垃圾回收器自动回收的资源)

④ 在组件中添加所有方法并打印

在组件中,所有方法的无序的排列(未按照执行顺序排列)。因为每个方法有自己的特有的执行条件,并非按照先后顺序执行。

@Component({
  selector: 'app-son',
  templateUrl: './son.component.html',
  styleUrls: ['./son.component.css']
})
export class SonComponent implements OnInit, AfterViewInit, AfterContentInit, OnChanges, DoCheck, AfterContentChecked, AfterViewChecked, OnDestroy {

  constructor() {
    console.log("constructor");
  }

  ngAfterViewChecked(): void {
    console.log("ngAfterViewChecked");
  }

  ngOnDestroy(): void {
    console.log("ngOnDestroy");
  }

  ngAfterContentChecked(): void {
    console.log("ngAfterContentChecked");
  }

  ngDoCheck(): void {
    console.log("ngDoCheck");
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log("ngOnChanges");
  }

  ngAfterContentInit(): void {
    console.log("ngAfterContentInit");
  }

  ngOnInit() {
    console.log("ngOnInit");
  }

  ngAfterViewInit(): void {
    console.log("ngAfterViewInit");
  }

}

执行结果:
Angular-07:组件生命周期_第6张图片

你可能感兴趣的:(angular,angular)