持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天。点击查看活动详情
我们通常使用两种情况:
- 父组件向子组件传值
- 子组件向父组件传值
通信方式:
-
父组件传到子组件 @Input 装饰器。
-
父组件监听子组件的事件
子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。子组件的 EventEmitter 属性是一个输出属性,通常带有@Output 装饰器。
- 父级调用 @ViewChild()传值
当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。
- 父组件和子组件通过服务来通讯
父组件和它的子组件共享同一个服务,利用该服务在组件家族内部实现双向通讯。
该服务实例的作用域被限制在父组件和其子组件内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。
父组件给子组件传值 @Input装饰器
父组件
<!-- 引入子组件 -->
<app-header [title]="title" [msgClick]='onMsgClick' [home]='this'></app-header>
public title: string = "我是父组件标题";
onMsgClick() {
alert("我是父组件事件")
}
子组件 使用
@Input接收传值
import { Component, OnInit, Input } from "@angular/core";
@Component({
selector: "app-header",
templateUrl: "./header.component.html",
styles: [],
})
export class HeaderComponent implements OnInit {
constructor() {}
@Input() title: string;
@Input() msgClick: Function;
@Input() home: any;
ngOnInit(): void {}
parentClick() {
this.msgClick();
this.home.onMsgClick();
}
}
@ViewChild 父组件获取子组件的属性和方法
ViewChild:是属性装饰器,用来从模板视图中获取匹配的元素。视图查询在 ngAfterViewInit钩子函数调用前完成,因此在 ngAfterViewInit 钩子函数中,才能正确获取查询的元素。
子组件
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-header",
templateUrl: "./header.component.html",
styles: [],
})
export class HeaderComponent implements OnInit {
public msg: string = "我是子组件msg";
constructor() {}
ngOnInit(): void {}
onChildClick() {
alert("我是子组件事件");
}
}
父组件
@ViewChild()接收子组件传值
- 在
html中通过注入属性(#名字)添加引用 #header调用子组件给子组件定义一个名称
<app-header #header></app-header>
<div>{{ childMsg }}</div>
<button (click)="onChild()">onChild</button>
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
})
export class ParentComponent implements OnInit {
constructor() { }
@ViewChild("header") header: any;
// ==> @ViewChild('header') input:ElementRef;
public childMsg: string
ngOnInit() {
}
ngAfterViewInit() {
console.log(this.header.msg);
setTimeout(() => {
this.childMsg = this.header.msg;
});
}
onChild() {
this.header.onChildClick();
}
}
子组件通过@Output 触发父组件
子组件引入
Output和EventEmitter
import { Component, OnInit, Output, EventEmitter } from "@angular/core";
@Component({
selector: "app-header",
templateUrl: "./header.component.html",
styles: [],
})
export class HeaderComponent implements OnInit {
/*用EventEmitter 和output 装饰器配合使用<string>指定类型变量*/
@Output() private outer = new EventEmitter<string>();
constructor() {}
ngOnInit(): void {}
// 子组件通过EventEmitter 对象outer 实例广播数据
sendParent() {
this.outer.emit("msg from child");
}
}
父组件调用子组件的时候,定义接收事件
outer就是子组件的EventEmitter对象outer名称和子组件自定义保持一致- 接收子组件传递过来的数据,父组件接收到数据会调用自己的
runParent方法,这个时候就能拿到子组件的数据
<app-header (outer)="runParent($event)"></app-header>
runParent(msg:string){
alert(msg);
}
最后
可以在同一个子组件上使用 @Input() 和 @Output(),下一篇更新同时使用@Input() 和 @Output()