前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Angular @Input @Output 通信 事件发射 事件处理
AnAngular组件与依赖注入

父组件如何通过 @Input() 和 @Output() 与子组件通信?当子组件发出事件后,父组件如何处理?

@Input() 和 @Output() 是 Angular 在模板中实现父子组件通信的官方通道,前者由父向子传值,后者通过 EventEmitter 将子组件内部事件发出,父组件在模板中绑定处理函数来消费该事件。

前端进阶之旅 · 一题精讲更新于 2026.09.05
Angular#组件与依赖注入#安全#表单
先看核心答案
理解线索

父子组件通信的通道

  1. 输入属性父向子传数据,子组件用 @Input() 声明
  2. 输出事件子组件用 EventEmitter 声明并主动 emit
  3. 模板绑定父模板用 [prop] 和 (event) 建立连接

输入输出都是单向的,数据流沿组件树自上而下,事件自下而上,不直接双向绑定。

核心回答

先记住这个答案

父组件在模板中使用属性绑定 [childProp]="parentValue" 将数据传给子组件,子组件通过 @Input() 声明接收。子组件可通过 @Output() someEvent = new EventEmitter<T>() 定义事件,并在合适时机调用 emit(value) 发送通知;父组件在模板中通过 (someEvent)="handler($event)" 绑定处理函数,Angular 会在事件触发时自动调用 handler。

  • 输入属性单向传值,修改需由父组件处理。
  • 输出事件通过 EventEmitter.emit 同步触发。
  • 父组件用事件绑定接收并对 $event 处理。

@Input 与 @Output 的运行机制

@Input() 装饰器将属性标记为可被父组件静态绑定。Angular 在变更检测时发现父组件的绑定值变化,就会从父组件更新到子组件的属性。注意这种传递总是单向的,子组件内部若给输入属性赋值,不会同步回父组件,只会影响自身当前实例。因此输入属性的变化只能在父组件侧引起,子组件需要修改时应该通过事件通知父组件来改。

@Output() 装饰器定义的属性必须是 EventEmitter 类实例,通常命名时避免以 on 开头。当子组件调用 emitter.emit(value) 时,Angular 会同步触发父组件模板中绑定的处理函数,$event 就是传入的 value。这一过程基于 Angular 的事件绑定机制,不是 DOM 事件冒泡,处理函数是在父组件的上下文中执行的。

如果想给事件附加额外信息,可直接在 emit 参数中传对象。父组件处理函数若需要访问当前组件,可使用箭头函数或在类中定义方法,但 Angular 已确保 this 正确指向父组件。

购物车数量选择器的实践

假设父组件显示商品信息,子组件是带有加减按钮的数量选择器。父组件将库存上限 stockUpperLimit 传给子组件的 @Input max。子组件内部维护当前数量 count,用户点击加号时若 count < max 才允许增加,随后通过 @Output() countChange = new EventEmitter<number>() 把新 count 传给父组件。父组件模板中写 (countChange)="onCountChange($event)"。

父组件的 onCountChange 收到新值后,先校验不越界,再调用购物车服务更新后端购物车项,同时修改父组件中的总价等派生数据。由于子组件不会直接改父组件的输入对象,而是通过事件请求修改,保证了数据流的清晰和单向性。当商品被移除或库存变化时,父组件会重新绑定一个新的 max,子组件 ngAfterViewChecked 或 ngOnChanges 中需处理限制。

何时容易失效及避免措施

当把数组或对象作为输入传给子组件时,子组件若直接修改其属性(例如 items.push)会同时改变父组件中的对象,因为共享引用。这会让输入数据流变得难以追踪,也容易造成不一致。正确做法是子组件用 Object.assign 或解构创建副本,只修改自己的副本,然后通过 emit 把新数据交给父组件,由父组件替换整个对象。

另一个失效点是输出事件触发后,父组件处理函数中对父子进行同步修改可能触发循环变更检测错误。Angular 的差异比较器在开发模式下检测到值循环变化时会报错。通常可把发送事件放到 setTimeout 中异步触发,或调整数据结构使父组件更新不引起子组件输出再次变化。

回答前,多想一步

容易答错的地方

认为 @Output 可以像方法调用一样返回值
@Output 是事件发射器,调用 emit 只发送通知,没有返回值。若需要父子组件间的参数回传,应让父组件将回调函数通过 @Input 传入,或通过双向绑定语法(如 [(value)])配合升级事件,而不是依赖事件返回值。
误以为 EventEmitter emit 是异步的
EventEmitter.emit 会同步调用已注册的监听器,包括父组件绑定的事件处理函数。所有监听器执行完毕后,emit 才返回。如果需要在处理函数后执行某些逻辑,必须通过 Promise.resolve 或 setTimeout 手动制造异步点,而不是依赖 emit 本身的特性。
试着用自己的话回答

面试官还会怎么问?

Angular 中输出事件名要不要加 on 前缀?

推荐不加 on。Angular 官方指南中虽然允许,但事件名应描述发生了什么,例如 countChange 而不是 onCountChange。组件模板中绑定事件时通常读起来更自然,也与内置事件如 (click) 保持一致。

如果子组件要同步父组件的输入,哪种方式最稳妥?

最稳妥的是子组件不直接修改输入属性,而是通过输出事件把新值传给父组件,父组件负责更新模型。若只是本地临时显示,可把输入赋值给内部属性,通过 ngOnChanges 监听变化再同步,避免直接写回原属性。

@Input 的值在子组件中何时可以访问?

在 ngOnInit 中已可用,但在 constructor 中不可访问,因为 Angular 尚未将绑定值赋值。更早的时序可在 ngOnChanges 中首次被调用时访问,此时输入属性已成功传入。

从一道题,走向一组知识

把知识连起来

组件与依赖注入

在 Angular 组件中,模板如何通过属性绑定和事件绑定与组件类交互?请说明其数据流方向与生命周期时机。

同属「组件与依赖注入」专题,接着看 Angular 属性绑定 事件绑定 模板与组件交互 数据流 在具体场景中的处理方式。

组件与依赖注入

在 Angular 中,服务作为依赖注入提供者时,作用域是如何决定其实例共享范围的?不同层级的 providers 有何影响?

同属「组件与依赖注入」专题,接着看 Angular 依赖注入 服务提供者 作用域 实例共享范围 在具体场景中的处理方式。

参考资料

  • Anatomy of a component

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. @Input 与 @Output 的运行机制
  3. 购物车数量选择器的实践
  4. 何时容易失效及避免措施
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑