第4章:组件通信与生命周期详解

章节速览:本章聚焦 Angular 组件间通信的四种核心方式(@Input/@Output、服务通信、ContentChild/ContentChildren)以及生命周期钩子的典型应用场景。掌握这些知识是应对中高级面试的必备能力。
生命周期钩子应用场景 ngOnChanges @Input 属性变化时触发 ngOnInit 组件初始化·数据加载 ngAfterViewInit 视图准备就绪后的操作 ngOnDestroy 清理订阅 / 定时器 ngDoCheck 自定义变更检测 注:结合 @Input/@Output、服务、ContentChild 使用,形成完整通信链路

面试问答卡片

问题 1:请描述 @Input 和 @Output 的工作原理及使用场景

考察点是否理解属性绑定与事件发射的机制、装饰器语法、变更检测影响
回答框架定义 → 数据流方向 → 实际代码示例 → 注意事项(OnPush、不可变数据)
示例回答@Input 通过属性绑定从父组件接收数据,@Output 使用 EventEmitter 向父组件发射事件。典型场景:子组件展示输入数据,用户操作后 emit 事件通知父组件更新。注意:配合 OnPush 策略时需传递新对象引用。
可能追问@Input setter 与 ngOnChanges 的区别?如何实现双向绑定?
避坑提醒避免直接修改 @Input 对象属性;EventEmitter 必须手动引入;装饰器名不要拼错。

问题 2:组件间通过服务通信的优缺点是什么?与 @Input/@Output 有何区别?

考察点服务共享状态的意识、RxJS Subject/BehaviorSubject 使用、层级关系解耦
回答框架服务作为中介层 → 跨级/兄弟组件通信场景 → 与父子通信的对比 → 使用 RxJS 管理状态
示例回答服务通信适合无直接父子关系的组件,例如兄弟组件或深层嵌套。通过注入共同服务,使用 Subject/BehaviorSubject 订阅状态变化。优点:解耦强;缺点:需要手动管理订阅生命周期,多使用 ngOnDestroy 取消订阅。
可能追问为什么推荐用 BehaviorSubject 而非 Subject?组件销毁后如何避免内存泄漏?
避坑提醒服务中 Subject 若未 complete 会导致内存泄漏;多组件共享同一服务实例时注意作用域(providers 层级)。

问题 3:ContentChild 与 ContentChildren 的使用场景?配合生命周期钩子的注意事项

考察点投影内容(ng-content)的组件获取、AfterContentInit 钩子、与 ViewChild 的区别
回答框架ContentChild 定义 → 在 ngAfterContentInit 中访问 → 不能用于视图子组件 → 配合 @Directive 操作投影元素
示例回答ContentChild 用于获取 ng-content 投影进来的子组件或指令实例。必须在 ngAfterContentInit 钩子中访问,因为此时投影内容才完成初始化。典型场景:Tab 面板内获取 Tab 标题组件以控制高亮。
可能追问ContentChild 与 ViewChild 的查询时机差异?如何通过 ContentChild 获取多个投影元素?
避坑提醒切勿在构造函数或 ngOnInit 中使用 ContentChild,值为 undefined;ContentChildren 返回 QueryList 需在 ngAfterContentInit 中订阅 changes。

项目案例章节

项目名称:智能表单配置平台(低代码表单引擎)

业务背景企业内控系统需要动态配置上百种审批表单,由运营人员拖拽组件生成表单,后端存储配置 JSON,前端渲染。
规模指标表单组件库 80+ 个、日活用户 2000+、单页面最深层级组件嵌套 7 层
技术栈Angular 15 + PrimeNG + RxJS + ngx-formly + 自定义动态组件解析器
核心难点① 深层嵌套组件父子通信(@Input/@Output 传递过多);② 动态组件销毁时未取消订阅导致内存泄漏;③ 投影内容中 ContentChild 获取时机错误
面试高频追问你们如何解决深层嵌套中的通信混乱?动态组件销毁时如何确保清理?ContentChild 在什么钩子后可用?
可迁移话术我们采用服务 + BehaviorSubject 统一管理表单状态,配合 ngOnDestroy 中调用 complete();对投影内容统一在 ngAfterContentInit 中初始化,避免空指针。
💡 面试加分建议:在回答组件通信时,主动提及 Angular 的“单向数据流”和“OnPush 变更检测”原则,并举例说明自己在项目中如何权衡 @Input/@Output 与服务的分工。面试官更看重你在真实场景中的设计决策能力。