学习Angular的时候总是搞不清楚ngOnInit和constructor的区别。来说明一下。
**
ngOnInit和constructor
**
//一个组件的 ts文件中:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
export interface TopMenu {
title: string;
link: string;
}
@Component({
selector: 'app-scrollable-tab',
templateUrl: './scrollable-tab.component.html',
styleUrls: ['./scrollable-tab.component.scss']
})
export class ScrollableTabComponent implements OnInit {
selectedIndex = -1;
title = 'zheshidiyige ngxiangmu';
@Input() menus: TopMenu[] = [];
@Output() tabSelected = new EventEmitter(); //事件发射器
//
constructor( //在这里引入一些上面引入的外部资源。在当前组件使用 ) {
//在这里写入一些事件,当ScrollableTabComponent这个类被实例化时执行
}
//这里写入的事件也是用于初始化操作的。
//ngOnInit是Angular中OnInit钩子的实现。用来初始化组件。
ngOnInit(): void {
handleSelection(index: number) {
this.selectedIndex = index
this.tabSelected.emit(this.menus[this.selectedIndex])
// console.log(this.tabSelected,'this.tabSelected')
}
}
在说他俩区别之前先看一下ng的生命周期钩子调用顺序
1、ngOnChanges – 当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。
2、ngOnInit() – 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。
在第一轮ngOnChanges()完成之后调用,只调用一次。
3、ngDoCheck – 自定义的方法,用于检测和处理值的改变。
4、ngAfterContentInit – 在组件内容初始化之后调用,只适用于组件
5、ngAfterContentChecked – 组件每次检查内容时调用,只适用于组件
6、ngAfterViewInit – 组件相应的视图初始化之后调用,只适用于组件
7、ngAfterViewChecked – 组件每次检查视图时调用,只适用于组件
8、ngOnDestroy – 当Angular每次销毁指令/组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。在Angular销毁指令/组件之前调用。
结合上面一大段文字,我们进行实际的代码操作看一下执行顺序。
constructor() {
console.log('constructor组件构造调用')
}
ngOnInit(): void {
console.log('组件初始化')
}
执行顺序入下图
控制台输出表明,在constructor中执行的任务会比ngOnlint先执行。
当组件数据发生变化的时候才会触发ngOnlint
既然ngOnchanges是输入属性值变化的时候调用,并且ngOnInit是在ngOnchanges执行完之后才调用,而constructor是在组件就实例化的时候就已经调用了,这也就是说,在constructor中我们是取不到输入属性的值的。
**
ngOnchanges
**
ngOnchanges是在输入属性值变化的时候调用,我们根据上面的例子做一些加工:
在组件的@Input 属性发生变化的时候调用
<app-scrollable-tab [menus]="topMenus" (tabSelected)="handleTabSelected($event)"
[backgroundColor]="srcollableTabBgColor" titleColor="#fff" titleActiveColor="yellow" indicatorCollr="yellow">
</app-scrollable-tab>
在html中标签中传入一个动态属性值:srcollableTabBgColor
在他对应的ts文件中,把这个值改为动态的:
export class AppComponent {
srcollableTabBgColor = 'red'
//中间过程略过
handleTabSelected(topMenu: TopMenu) {
//在这里修改一下srcollableTabBgColor 这个属性
const colors = ['red', 'blue', 'yellow']
const idx = Math.floor(Math.random() * 3)
this.srcollableTabBgColor = colors[idx]
}
}
当我点击了属性值发生变化,onChange函数就会被调用。可以被调用多次。
同时也能看到constructor和Oninit在组件中只会执行一次。
//这里附加上组件内部输出的函数
ngOnChanges(changes: SimpleChanges): void {
console.log('组件输入属性改变', changes)
}
**
ngDoCheck
**
脏值检测,也就是说检测属性值的变化。和ngOnChanges有一些类似。
但是ngOnChanges是你主动想检测一些属性值的变化,ngDoCheck是ng框架为我们进行一些数据上的检测。(说白了我现在也不太懂)
但是他会在组件加载的时候执行两次。
**
ngAfterContentInit
**
ngAfterContentInit 组件内容初始化。就是在我组件里可以像vue的插槽一样,插入一些内容。
插入方法就是在子组件中写入标签,在父组件里子组件标签中写入一些内容
<app-scrollable-tab [menus]="topMenus" (tabSelected)="handleTabSelected($event)"
[backgroundColor]="srcollableTabBgColor" titleColor="#fff" titleActiveColor="yellow" indicatorCollr="yellow">
<div>这是我想嵌套的内容</div>
</app-scrollable-tab>
而这个ngAfterContentInit是我整个组件内容都初始化完成的时候就执行了。
剩下的ngAfterContentChecked以及ngAfterViewInit都在整体练习demo中有输出。就不过度介绍了。
整个生命周期执行顺序就在下图