Angular25 组件的生命周期钩子

1 生命周期钩子概述

  组件共有9个生命周期钩子

  

  1.1 生命周期的执行顺序

    技巧01:测试时父组件传递对子组件的输入属性进行初始化操作

import { Component, Input, SimpleChanges, OnInit, OnChanges, DoCheck, AfterContentChecked, AfterViewInit, AfterContentInit, AfterViewChecked, OnDestroy } from ‘@angular/core‘;

let logIndex : number = 1;

@Component({
  selector: ‘life‘,
  templateUrl: ‘./life.component.html‘,
  styleUrls: [‘./life.component.scss‘]
})
export class LifeComponent implements OnInit, OnChanges, DoCheck,
AfterContentInit, AfterContentChecked, AfterViewInit,
AfterViewChecked, OnDestroy {

  @Input()
  name : string;

  logIt(msg : String) {
    console.log(`#${logIndex++} - ${msg}`);
  }

  constructor() {
    this.logIt("name属性在constructor里面的值为: " + this.name);
  }

  ngOnInit() {
    this.logIt("ngOnInit");
  }

  ngOnChanges(changes : SimpleChanges){
    this.logIt("name属性在ngOnChanges里面的值为: " + this.name);
  }

  ngDoCheck() {
    this.logIt("ngDoCheck");
  }

  ngAfterContentInit() {
    this.logIt("ngAfterContentInit");
  }

  ngAfterContentChecked() {
    this.logIt("ngAfterContentChecked");
  }

  ngAfterViewInit() {
    this.logIt("ngAfterViewInit");
  }

  ngAfterViewChecked() {
    this.logIt("ngAfterViewChecked");
  }

  ngOnDestroy() {
    this.logIt("ngOnDestroy");
  }

}

TS

    

2 ngOnChanges

  2.1 可变对象和不可变对象

    在JavaScript中string类型是不可变对象,自定义的对象是可变对象;例如:

      var a = "hello";   ->  变量a中存储的是字符串“hello”对应的内存地址

      a = "warrior";  -> 变量a中存储的是字符串“warrior”对应的内存地址

      结论:将不同的字符串赋值给同一个变量时,变量的值会发生改变;所以string类型是不可变类型【PS: 跟Java一样】

      var user : {name : string} = {name : "warrior"};  -> 变量user中存储的是对象{name : "warrior"}对应的内存地址

      user.name = "fury"; -> 变量user中还是存储的对象{name : "fury”}对应的内存地址,而且{name : "warrior"}和{name : "fury”}是同一个对象,所以他们的内存地址相同,故变量user中存储的值没有发生改变,改变的仅仅是变量user所指向的那个对象中的内容而已

      结论:修改一个对象的内容并不会改变这个对象的内存地址,所以对象是可变对象

  2.2 ngOnChanges

    当输入属性的值发生改变时就会触发ngOnChanges

    技巧01:如果输入属性的类型是一个对象时,需要区分是可变对象还是不可变对象,只有不可变对象时才会触发ngOnChanges;总之记住只要输入属性的值发生改变才会触发ngOnChanges

    技巧02:ngOnChanges方法需要传入一个 SimpleChanges 类型的参数,可以利用该参数来查看输入属性改变前后的值,以及是否是初次赋值

    技巧03:JSON.stringfy() 方法在将数据转化成JSON时可以进行格式化,例如

  ngOnChanges(simpleChanges : SimpleChanges) {
    console.log(JSON.stringify(simpleChanges, null, 2));
  }

    2.2.1 子组件代码  

<div class="panel panel-primary">
  <div class="panel-heading">子组件</div>
  <div class="panel-body">
    <p>问候语:{{greeting}}</p>
    <p>姓名:{{user.name}}</p>
    <p>年龄:{{age}}</p>
    <p>
      消息:<input type="text" name="message" [(ngModel)]="message" />
    </p>
  </div>
  <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, EventEmitter, Output, Input, OnChanges, SimpleChanges } from ‘@angular/core‘;

@Component({
  selector: ‘child‘,
  templateUrl: ‘./child.component.html‘,
  styleUrls: [‘./child.component.scss‘]
})
export class ChildComponent implements OnInit, OnChanges {

  @Input()
  greeting : string;

  @Input()
  user : {name : string};

  @Input()
  age : number;

  message : string;

  currentDate : Date;

  constructor() { }

  ngOnInit() {
    this.currentDate = new Date();
    setInterval(() => {
      this.currentDate = new Date();
    }, 1000);
  }

  ngOnChanges(simpleChanges : SimpleChanges) {
    console.log(JSON.stringify(simpleChanges, null, 2));
  }

}

TS

    2.2.2 父组件代码    

<div class="panel panel-primary">
  <div class="panel-heading">父组件</div>
  <div class="panel-body">
    <p>
      问候语:<input type="text" name="greeting" [(ngModel)]="greeting" />
    </p>
    <p>
      姓名:<input type="text" name="name" [(ngModel)]="user.name" />
    </p>
    <p>
      年龄:<input type="number" [(ngModel)]="age" />
    </p>
    <child [greeting]="greeting" [user]="user" [age]="age"></child>
  </div>
  <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit } from ‘@angular/core‘;

@Component({
  selector: ‘parent‘,
  templateUrl: ‘./parent.component.html‘,
  styleUrls: [‘./parent.component.scss‘]
})
export class ParentComponent implements OnInit {

  greeting : string = "Hello";

  user : {name : string} = {name : "王杨帅"};

  age : number = 8;

  currentDate : Date;

  constructor() { }

  ngOnInit() {
    this.currentDate = new Date();
    setInterval(() => {
      this.currentDate = new Date();
    }, 1000);
  }

}

TS

    2.2.3 效果图

      

3 ngDoCheck

  3.1 变更检测机制

    angular中由zone.js去负责监听浏览器中所有异步事件(事件[单击、双击]、定时器、ajax)来保证模板和组件属性的变化时同步的;

    只要zone.js检测到有异步事件发生时所有监测机制是默认检测机制的组件都会触发ngDoCheck

    应用:当输入属性的类型是可变对象时,即使可变对象的内容发生了变化 ngOnchanges 也不会被调用,但是 ngDoCheck 会被调用;所以我们可以利用 ngDoCheck 来检测可变对象的变化

    坑01:zone.js检测到任何一个组件有异步事件发生都会让所有采用默认变更检测机制的组件执行 ngDoCheck,所以 ngDoCheck 方法要慎用,而且逻辑不能太复杂,不然会影响性能

  3.2 变更检测策略

    3.2.1 default

      angular默认的变更检测策略

      如果所有的组件都是默认的变更检测策略,那么当一个组件发生改变时angular会对所有的组件进行变更检查

    3.2.2 onPush

      待更新...

  3.3 代码汇总

    3.3.1 父组件代码

<div class="panel panel-primary">
  <div class="panel-heading">父组件</div>
  <div class="panel-body">
    <p>
      问候语:<input type="text" name="greeting" [(ngModel)]="greeting" />
    </p>
    <p>
      姓名:<input type="text" name="name" [(ngModel)]="user.name" />
    </p>
    <p>
      年龄:<input type="number" [(ngModel)]="age" />
    </p>
    <child [greeting]="greeting" [user]="user" [age]="age"></child>
  </div>
  <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit } from ‘@angular/core‘;

@Component({
  selector: ‘parent‘,
  templateUrl: ‘./parent.component.html‘,
  styleUrls: [‘./parent.component.scss‘]
})
export class ParentComponent implements OnInit {

  greeting : string = "Hello";

  user : {name : string} = {name : "王杨帅"};

  age : number = 8;

  currentDate : Date;

  constructor() { }

  ngOnInit() {
    this.currentDate = new Date();
    // setInterval(() => {
    //   this.currentDate = new Date();
    // }, 1000);
  }

}

TS

    3.3.2 子组件代码

<div class="panel panel-primary">
  <div class="panel-heading">子组件</div>
  <div class="panel-body">
    <p>问候语:{{greeting}}</p>
    <p>姓名:{{user.name}}</p>
    <p>年龄:{{age}}</p>
    <p>
      消息:<input type="text" name="message" [(ngModel)]="message" />
    </p>
  </div>
  <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
</div>

HTML

import { Component, OnInit, EventEmitter, Output, Input, OnChanges, SimpleChanges } from ‘@angular/core‘;
import { DoCheck } from ‘@angular/core/src/metadata/lifecycle_hooks‘;

@Component({
  selector: ‘child‘,
  templateUrl: ‘./child.component.html‘,
  styleUrls: [‘./child.component.scss‘]
})
export class ChildComponent implements OnInit, OnChanges, DoCheck {

  @Input()
  greeting : string;

  @Input()
  user : {name : string};

  oldName : string; // 存储上一次的值
  changeNum : number = 0; // 非本组件触发ngDoCheck方法的次数
  changeDetected : boolean; // 是否是本组件触发ngDoCheck方法

  @Input()
  age : number;

  message : string;

  currentDate : Date;

  constructor() { }

  ngOnInit() {
    this.currentDate = new Date();
    // setInterval(() => {
    //   this.currentDate = new Date();
    // }, 1000);
  }

  ngOnChanges(simpleChanges : SimpleChanges) {
    console.log(JSON.stringify(simpleChanges, null, 2));
  }

  ngDoCheck() : void {

    // 如果检测到是本组件的输入属性变化
    if (this.user.name !== this.oldName) {
      this.changeDetected = true;
      console.log("ngDoCheck: user.name 从 "+ this.oldName +" 变成了 "+ this.user.name +" ");
      this.oldName = this.user.name;
    }

    if (this.changeDetected) {
      this.changeNum = 0; // 本组件触发的ngDoCheck就进行清零操作
    } else { // 非本组件触发的ngDoCheck方法就进行加一操作
      this.changeNum = this.changeNum + 1;
      console.log("ngDoCheck: user.name没有变化,ngDoCheck方法被调用了" + this.changeNum + "次");
    }

    this.changeDetected = false;

  }

}

TS

    3.3.3 效果展示

      

    

原文地址:https://www.cnblogs.com/NeverCtrl-C/p/9249017.html

时间: 2024-07-30 22:50:24

Angular25 组件的生命周期钩子的相关文章

第九篇:Vue组件的生命周期钩子

组件的生命周期钩子 一.组件的生命周期:一个组件从创建到销毁的整个过程 二.生命周期钩子:在一个组件生命周期中,会有很多特殊的时间节点,且往往会在特定的时间节点完成一定的逻辑,特殊的事件节点可以绑定钩子 注:钩子 - 提前为某个事件绑定方法,当满足这个事件激活条件时,方法就会被调用 | 满足特点条件被回调的绑定方法就称之为钩子 <template> <div class="goods"> <Nav /> </div> </templ

简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序

首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted 子组件更新过程父beforeUpdate->子beforeUpdate->子up

Vue 组件生命周期钩子

Vue 组件生命周期钩子 # 1)一个组件从创建到销毁的整个过程,就称之为组件的生命周期 # 2)在组件创建到销毁的过程中,会出现众多关键的时间节点, 如: 组件要创建了.组件创建完毕了.组件数据渲染完毕了.组件要被销毁了.组件销毁完毕了 等等时间节点, 每一个时间节点,vue都为其提供了一个回调函数(在该组件到达该时间节点时,就会触发对应的回调函数,在函数中就可以完成该节点需要完成的业务逻辑) # 3)生命周期钩子函数就是 vue实例的成员 beforeCreate 组件创建了,但数据和方法还

Vue ---- 组件文件分析 组件生命周期钩子 路由 跳转 传参

目录 Vue组件文件微微细剖 Vue组件生命周期钩子 Vue路由 1.touter下的index.js 2.路由重定向 3.路由传参数 补充:全局样式导入 路由跳转 1. router-view标签 2. router-link标签 3.逻辑跳转 this.$router 控制路由跳转 this.$route 控制路由数据 Vue组件文件微微细剖 组件在view 文件中创建 如果需要用到其他小组件可以 在 component文件中创建并导入 view文件下: <template> <di

Vue 实例中的生命周期钩子

Vue 框架的入口就是 Vue 实例,其实就是框架中的 view model ,它包含页面中的业务处理逻辑.数据模型等,它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑. Vue 实例 在文档中经常会使用 vm 这个变量名表示 Vue 实例,在实例化 Vue 时,需要传入一个选项对象,它可以包含数据(data).模板(template).挂载元素(el).方法(methods).生命周期钩子(lifecyclehook)等选项. Vue 实例化的选项 需要注意的

React组件的生命周期

整个组件,从创建组件类开始,到渲染,到消亡的过程,就是组件的生命周期. 组件的生命周期可以分为三个阶段: 挂载阶段 更新阶段 卸载阶段 挂载阶段 在这个过程中,会触发以下几个事件 getDefaultProps,设置默认属性 getInitialState,设置初始状态 componentWillMount 即将挂载 render 渲染,就是挂载 componentDidMount 挂载完成 <!DOCTYPE html> <html> <head> <meta

vue组件的生命周期

先来张组件生命周期的示意图: 文档里是这样描述的:你不需要立马弄明白所有的东西,不过以后它会有帮助.传送门. Vue所有的生命周期钩子自动绑定在this上下文到实例中,因此你可以访问数据,对属性和方法进行运算.这意味着你不能使用箭头函数来定义一个生命周期方法.这是因为箭头函数绑定了父上下文,因此this与你期待的Vue实例不同. 1.beforeCreate 在实例初始化之后,数据观测和event/watcher时间配置之前被调用. 2.created 实例已经创建完成之后被调用.在这一步,实例

react.js 从零开始(二)组件的生命周期

什么是生命周期? 组件本质上是一个状态机,输入确定,输出一定确定. 当状态改变的时候 会触发不同的钩子函数,可以让开发者做出响应.. 一个组件的生命周期可以概括为 初始化:状态下 可以自定义的函数 getDefaultProps object getDefaultProps() 在组件类创建的时候调用一次,然后返回值被缓存下来.如果父组件没有指定 props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props (使用 in 检测属性). 该方法在任何实例创建之前调用,因此不

Angular2 -- 生命周期钩子

组件生命周期钩子 指令和组件的实例有一个生命周期:新建.更新和销毁.每个接口都有唯一的一个钩子方法,它们的名字是由接口名加上 ng前缀构成的.比如,OnInit接口的钩子方法叫做ngOnInit.指令和组件ngOnInit:当Angular初始化完成数据绑定的输入属性后,用来初始化指令或者组件.ngOnChanges:当Angular设置了一个被绑定的输入属性后触发.该回调方法会收到一个包含当前值和原值的changes对象.ngDoCheck:用来检测所有变化(无论是Angular本身能检测还是