• 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() { }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    export class OtherComponent implements OnInit{
    
      constructor(
        private TestService: TestService
      ) {
        console.log("this.TestService--", this.TestService.testTip);  // test,来自服务的消息
    
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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


    1.2 ngOnInit

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

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

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

    
    
    <app-son [sonName]="'王二小'">app-son>
    
    • 1
    • 2
    • 3

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

    // 子组件类
    export class SonComponent implements OnInit {
    
      @Input() sonName: string = '';
    
      constructor() { }
    
      ngOnInit() {
        console.log("sonName", this.sonName);   // 王二小
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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


    ② 更新阶段

    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>
    
    • 1
    • 2
    • 3
    // 父组件类
    
      sonName: string = '王二小';
    
      changeName() {
        this.sonName = "李四";
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    // 子组件类
    
      @Input() sonName: string;
    
      ngOnChanges(changes: SimpleChanges): void {
        console.log("changes", changes);
        console.log("sonName", this.sonName);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 基本数据类型的值改变可以在该方法中被检测到
    2. SimpleChanges对象:包含当前值和变化前的值。输入属性值发生变化时触发。
      在这里插入图片描述

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

    1. 给子组件传递一个对象 sonInfo,值为:{ name: “王二小”, age: 18 }。
    2. 定义一个按钮,点击按钮时将该对象的属性改变。
    
    
    <app-son [sonInfo]="sonInfo">app-son>
    <button (click)="changeInfo()">换个信息button>
    
    • 1
    • 2
    • 3
    • 4

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

    // 父组件类
    
      sonInfo = { name: "王二小", age: 18 };
    
      changeInfo() {
        this.sonInfo.name = "李四";
        this.sonInfo.age = 3;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 在子组件类中接收该对象sonInfo,并在ngOnChanges中添加打印
    // 子组件类
    
     @Input() sonInfo: Object;
    
      ngOnChanges(changes: SimpleChanges): void {
        console.log("changes", changes);
        console.log("sonInfo", this.sonInfo);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    
    
    <p>{{sonInfo | json}}p>
    
    • 1
    • 2
    • 3

    最终结果:

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

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

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

    最终结果:
    每次点击按钮,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");
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

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

  • 相关阅读:
    质量小议14 -- DevOps
    OpenSSL生成PKCS#8私钥和公钥
    【附源码】计算机毕业设计java养老院老人日常生活管理系统设计与实现
    前端SVG的学习
    Wpf 使用 Prism 实战开发Day21
    7数据结构与算法基础——软件设计师
    springboot-配置文件优先级
    拍摄的vlog视频画质模糊怎么办?视频画质高清修复
    C#中关于字符串的使用
    JavaScript变量和作用域简介
  • 原文地址:https://blog.csdn.net/weixin_43964866/article/details/134004101