Angular-07:组件生命周期

该表按照执行顺序编写

编号函数名实现名说明
1constructorconstructor接收服务实例化对象
2ngOnChangesOnChanges当输入属性值发生变化时执行
3ngOnInitOnInit在首次接收到输入属性值后执行
4ngDoCheckDoCheck主要用于调试,每次变化检测发生时调用
5ngAfterContentInitAfterContentInit当内容投影初始渲染完成后调用
6ngAfterContentCheckedAfterContentChecked内容投影更新完成后执行
7ngAfterViewInitAfterViewInit当组件视图渲染完成后调用
8ngAfterViewCheckedAfterViewChecked组件视图更新完成后执行
9ngOnDestroyOnDestroy组件被销毁之前调用

① 挂载阶段

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

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,来自服务的消息

  }
}

结果:
在这里插入图片描述


1.2 ngOnInit

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

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

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

<!-- 父组件模板 -->

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

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

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

  @Input() sonName: string = '';

  constructor() { }

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

}

结果:
在这里插入图片描述


② 更新阶段

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对象:包含当前值和变化前的值。输入属性值发生变化时触发。
    在这里插入图片描述

例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. 但是在子组件模板中可以看到,该对象已经由最初的 “王二小” 变为了 “李四” 。在这里插入图片描述

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

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

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

最终结果:
每次点击按钮,ngOnChanges都会检测到该对象的变化
在这里插入图片描述


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");
  }

}

执行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值