@Input 和 @Output 是父子组件通信的标准方式:@Input 向下传递数据(父组件 → 子组件),@Output 向上发送事件(子组件 → 父组件)。这体现了通用的「数据向下,事件向上」的模式。
@Input — 数据向下流动
ts
{ , } ;
({ : , : })
{
() user!: ;
() showEmail = ;
}
<!-- parent passes data via property binding -->
<app-user-card [user]="currentUser" [showEmail]="true"></app-user-card>
// child emits an event the parent can listen to
import { Component, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-user-card",
template: `<button (click)="onDelete()">Delete</button>`,
})
export class UserCardComponent {
@Output() deleted = new EventEmitter<number>(); // declares an output event
onDelete() {
this.deleted.emit(this.user.id); // emit with a payload
}
}
<!-- parent listens via event binding -->
<app-user-card [user]="u" (deleted)="removeUser($event)"></app-user-card>
子组件通过 EventEmitter 发出事件;父组件使用 (eventName) 绑定它并通过 $event 接收数据。子组件永远不会直接修改父组件的数据——它通过发出事件来请求执行某个操作。
Parent ──[user]──────────────→ Child (@Input: data down)
Parent ←──(deleted)=removeUser─ Child (@Output: events up)
name = input<string>(); // signal-based @Input (newer Angular)
deleted = output<number>(); // signal-based @Output
最近的 Angular 添加了基于信号的 input()/output() 函数作为替代方案。
@Input/@Output 是 Angular 中父子组件通信和可复用组件的核心——它们强制实施单向数据流(通过输入向下,通过事件向上),保持数据的可预测性和组件的解耦。
理解这对装饰器对于组合任何非平凡的 Angular UI 至关重要;对于无关组件之间的通信,你应该改用共享服务或状态管理库。