Angular - 组件生命周期函数详解
Angular 的生命周期函数是组件和指令在创建、更新和销毁过程中自动调用的钩子方法,用于在关键阶段执行自定义逻辑。以下是核心生命周期函数及其应用场景(按调用顺序排列):
1. ngOnChanges()
- 调用时机:
当输入属性(@Input
绑定)的值发生变化时调用(首次调用在ngOnInit
前)。 - 参数:
SimpleChanges
对象(包含当前/上一次属性值)。 - 应用场景:
- 响应输入属性的变化(如表单配置更新)。
- 根据外部传入的数据动态调整组件状态。
ngOnChanges(changes: SimpleChanges) { if (changes['inputProp']) { console.log('输入属性变化:', changes['inputProp'].currentValue); } }
2. ngOnInit()
- 调用时机:
组件初始化完成(已设置输入属性),但视图尚未渲染。仅调用一次。 - 应用场景:
- 初始化数据(如从 API 加载初始数据)。
- 设置默认状态或执行一次性配置。
ngOnInit() { this.loadData(); // 初始化数据请求 }
3. ngDoCheck()
- 调用时机:
每次变更检测周期运行(包括非数据绑定触发的变更)。 - 应用场景:
- 手动检测 Angular 忽略的变更(如对象内部属性变化)。
- 配合
ChangeDetectorRef
实现自定义变更检测逻辑。
ngDoCheck() { if (this.obj.property !== this.previousValue) { this.cdr.markForCheck(); // 手动标记变更 } }
4. ngAfterContentInit()
- 调用时机:
组件内容投影(<ng-content>
)初始化完成。仅调用一次。 - 应用场景:
- 访问通过
@ContentChild
/@ContentChildren
查询的投影内容。 - 初始化依赖投影内容的逻辑。
ngAfterContentInit() { console.log('投影内容已渲染:', this.contentChild); }
- 访问通过
5. ngAfterContentChecked()
- 调用时机:
每次 Angular 检查投影内容后调用(可能频繁触发)。 - 应用场景:
- 响应投影内容的变更(需注意性能影响)。
- 执行与投影内容相关的后处理逻辑。
6. ngAfterViewInit()
- 调用时机:
组件视图及子视图初始化完成。仅调用一次。 - 应用场景:
- 访问 DOM 元素(通过
@ViewChild
/@ViewChildren
)。 - 初始化第三方库(如图表、地图)。
ngAfterViewInit() { this.chart = new Chart(this.canvas.nativeElement); // 操作 DOM }
- 访问 DOM 元素(通过
7. ngAfterViewChecked()
- 调用时机:
每次 Angular 检查组件视图及子视图后调用。 - 注意:
避免在此处修改数据,否则可能触发ExpressionChangedAfterChecked
错误。 - 应用场景:
- 监听视图变更完成(谨慎使用)。
8. ngOnDestroy()
- 调用时机:
组件销毁前(如路由导航移除组件时)。 - 应用场景:
- 资源清理(取消订阅、清除定时器、断开事件监听)。
- 避免内存泄漏。
ngOnDestroy() { this.subscription.unsubscribe(); // 取消订阅 clearInterval(this.timer); // 清除定时器 }
生命周期执行顺序总结
创建阶段:
ngOnChanges → ngOnInit → ngDoCheck → ngAfterContentInit → ngAfterContentChecked → ngAfterViewInit → ngAfterViewChecked
更新阶段(输入变化):
ngOnChanges → ngDoCheck → ngAfterContentChecked → ngAfterViewChecked
销毁阶段:
ngOnDestroy
最佳实践建议
- 减少
ngDoCheck
/ngAfterViewChecked
中的复杂逻辑:
这些方法调用频繁,避免阻塞主线程。 - 视图操作在
ngAfterViewInit
中进行:
确保 DOM 已渲染完成。 - 务必在
ngOnDestroy
中释放资源:
防止内存泄漏(尤其是 Observable 订阅)。 - 避免在
ngAfterViewChecked
中修改数据:
可能引发变更检测循环错误。
理解生命周期钩子有助于在正确时机执行代码,提升应用性能和可维护性。