在 Angular 中,组件之间通信的方式有很多,具体使用哪一种方式,取决于组件之间的关系(父子、兄弟、无直接关系)以及项目复杂度。以下是常见的几种通信方式:
一、父子组件通信
1. @Input() —— 父组件向子组件传值
// 子组件
@Input() title: string;
<!-- 父组件 -->
<app-child [title]="'Hello'"></app-child>
2. @Output() + EventEmitter —— 子组件向父组件传值
// 子组件
@Output() notify = new EventEmitter<string>();
someMethod() {
this.notify.emit('子组件发出的信息');
}
<!-- 父组件 -->
<app-child (notify)="onNotify($event)"></app-child>
二、兄弟组件通信
3. 使用共享服务 + Subject 或 BehaviorSubject
共享服务:
@Injectable({ providedIn: 'root' })
export class CommunicationService {
private messageSource = new Subject<string>();
message$ = this.messageSource.asObservable();
sendMessage(msg: string) {
this.messageSource.next(msg);
}
}
兄弟组件 A 发送消息:
constructor(private commService: CommunicationService) {}
send() {
this.commService.sendMessage('Hello from A');
}
兄弟组件 B 订阅消息:
ngOnInit() {
this.commService.message$.subscribe(msg => {
console.log('收到:', msg);
});
}
三、父组件访问子组件方法或属性
4. @ViewChild()
@ViewChild(ChildComponent) child!: ChildComponent;
ngAfterViewInit() {
this.child.someMethod();
}
四、通过路由传参(适用于非嵌套关系)
5. Router 路由参数或状态传递
- Query Params:
/detail?id=123 - Route Params:
/detail/123 - Navigation Extras:
this.router.navigate(['/detail'], {
state: { data: 'some data' }
});
五、使用 NgRx、Signal(Angular 16+)进行全局状态管理
- 当项目变大,通信复杂时,可以使用: NgRx / Akita / NGXS 等状态管理库--此方法可以另开一个专栏了,
- Angular 16+ 的 Signals + Injector +
inject()实现响应式共享状态
六、其他方式
-
本地存储(localStorage / sessionStorage)适合刷新页面后仍需共享数据。
-
RxJS的ReplaySubject、BehaviorSubject等实现缓存订阅