如何通過(guò)簡(jiǎn)單的代碼描述Angular父組件、子組件傳值
引言
對(duì)于稍微接觸過(guò)Angular組件的同學(xué)來(lái)說(shuō),組件間交互應(yīng)該沒(méi)有什么問(wèn)題。
本文想追求的是用一個(gè)通俗解釋?zhuān)瑤椭约豪斫獾母鼫?zhǔn)確。
零、知識(shí)鋪墊
CSS選擇器
在介紹父子組件之前,先要了解一個(gè)概念——selector、選擇器
我們定義一個(gè)新組件時(shí),一定會(huì)有這個(gè)屬性:
@Component({ selector: 'app-village-edit', ① templateUrl: './village-edit.component.html', styleUrls: ['./village-edit.component.scss'] })
其中①就是選擇器,就是告訴別的組件,如果想調(diào)用我這個(gè)組件,就要使用本組件的選擇器<selectorName></selectorName>
來(lái)調(diào)用。
本質(zhì)上就是定義了組件的HTML標(biāo)簽,就像常見(jiàn)的<p>
標(biāo)簽、<button>
標(biāo)簽一樣。
一、什么是父子組件
就像現(xiàn)實(shí)中父母和孩子的關(guān)系是相對(duì)的一樣,一個(gè)人對(duì)于它的父母來(lái)說(shuō),就承擔(dān)了孩子的角色;對(duì)于它的孩子來(lái)說(shuō)則承擔(dān)了父母的角色。
父組件和子組件也是相對(duì)的。
假設(shè),一個(gè)組件在自己的HTML模板中,通過(guò)選擇器(也就是特定的HTML標(biāo)簽)來(lái)調(diào)用其他組件時(shí)。我們稱(chēng)這個(gè)組件為父組件,而那個(gè)被調(diào)用的組件稱(chēng)為子組件。
二、父組件調(diào)用子組件的方法
定義了兩個(gè)類(lèi):
child.component.ts,它的選擇器selector是: 'app-child'
parent.component.ts,它的選擇器selector是: 'app-parent',
此時(shí),在parent組件的HTMl中引用child組件的選擇器:
<app-child></app-child>
這樣就完成了子組件的調(diào)用。
此時(shí),如果通過(guò)路由加載父組件,就會(huì)發(fā)現(xiàn)子組件也會(huì)在特定的位置被渲染出來(lái)。
三、父組件向子組件傳值
子組件使用@input裝飾器接收數(shù)據(jù)
子組件從父組件接收的值,會(huì)保存到子組件的變量中。
所以用來(lái)接收傳值的變量與普通變量唯一的區(qū)別,就是在常規(guī)的變量上增加一個(gè)@input()注解。
定義普通變量是這樣的:
master = 'Master';
如果用來(lái)接收傳值,只要改成這樣:
@Input() master = 'Master';
這樣,master變量默認(rèn)是'Master'字符串。
但如果父組件向其傳值,變量就變成了接收的值。
父組件使用方括號(hào)[]發(fā)送數(shù)據(jù)
常規(guī)方式調(diào)用子組件:
<app-child></app-child>
如果子組件可以接收數(shù)據(jù),就可以用[propertyName] = value的方法來(lái)傳值。
例如:
<app-child [master]="hero"> </app-child>
用這種寫(xiě)法可以實(shí)現(xiàn):一旦組件渲染完成后,子組件中的master變量就是'hero'的值了。
當(dāng)父組件中的變量值變化時(shí),子組件也會(huì)同步變化,也就是說(shuō),子組件可以監(jiān)聽(tīng)傳過(guò)來(lái)的值的變化信息。
升級(jí):子組件通過(guò)set方法監(jiān)聽(tīng)傳入數(shù)據(jù)變化
在上面的方式中,對(duì)于傳過(guò)來(lái)的值,雖然可以監(jiān)聽(tīng)變化,但局限在于:子組件只能直接使用傳入的值。
如果想對(duì)傳入的值進(jìn)行處理或過(guò)濾,就要稍微調(diào)整一下子組件。
常規(guī)情況下,子組件是通過(guò)給變量加上@Input裝飾器來(lái)接收參數(shù)的:
@Input() name = 'name';
如果想處理參數(shù),只需要把接收傳值的變量變成set方法即可:
@Input() get name(): string { return this._name; } set name(name: string) { // 此處可以增加其他處理邏輯 this._name = name; } private _name = '';
此時(shí),_name
是內(nèi)部變量,當(dāng)父組件對(duì)于name屬性傳入值的時(shí)候,會(huì)自動(dòng)執(zhí)行set name方法給_name
賦值并增加其他的處理邏輯。
另一種升級(jí):子組件通過(guò)ngOnChanges()生命周期鉤子監(jiān)聽(tīng)傳入數(shù)據(jù)變化
官方文檔中寫(xiě)到:“當(dāng)需要監(jiān)視多個(gè)、交互式輸入屬性的時(shí)候,ngOnChanges()比用屬性 setter 方法更合適。”
常規(guī)情況下,子組件是通過(guò)給變量加上@Input裝飾器來(lái)接收參數(shù)的:
@Input() param1 = 'string1'; @Input() param2 = 'string2';
當(dāng)我們要監(jiān)聽(tīng)多個(gè)變量的變化并做出反應(yīng)時(shí),可以用ngOnChanges()方法:
@Input() param1 = 'string1'; @Input() param2 = 'string2'; ngOnChanges(changes: SimpleChanges) { ① for (const propName in changes) { ② // 通過(guò)變量名獲取變化信息 const changedProp = changes[propName]; // 獲取上一個(gè)值 const from = JSON.stringify(changedProp.previousValue); ③ // 獲取當(dāng)前值 const to = JSON.stringify(changedProp.currentValue); ④ // 此處可以添加其他處理過(guò)程了 ⑤ } }
① 執(zhí)行ngOnChanges()方法時(shí),可以用一個(gè)SimpleChanges參數(shù)來(lái)獲得當(dāng)前組件所有參數(shù)的變化情況。
② 通過(guò)循環(huán)獲得每一個(gè)參數(shù)的上一個(gè)值和當(dāng)前值。
③ 獲得上一個(gè)值④ 獲得當(dāng)前值⑤ 根據(jù)業(yè)務(wù)邏輯添加其他處理過(guò)程
注:由于ngOnChanges方法調(diào)用非常頻繁,會(huì)導(dǎo)致性能問(wèn)題或者軟件崩潰,所以建議少用。
四、子組件向父組件傳值
子組件向父組件彈射事件
剛剛講到了子組件如何獲取父組件的傳入的變量,如何監(jiān)聽(tīng)父組件的變化,以及如何處理傳入的值。
接下來(lái)講反向的傳輸:父組件如何監(jiān)聽(tīng)子組件的變化,并做出反應(yīng)。
定義普通變量是這樣的:
param1 = 'String1';
如果想把這個(gè)變量暴露給父組件,需要在變量前加入@output()裝飾器,并且給他賦值一個(gè)變量彈射器:
@Output() param1 = new EventEmitter<string>();
此處EventEmitter是變量彈射器,EventEmitter需要一個(gè)確定的類(lèi)型。
但此時(shí),這個(gè)param1變量就不能再用等號(hào)"="賦值了,如果想讓父組件監(jiān)聽(tīng)到變化,就需要用彈射方法.emit
:
this.param1.emit("String2");
接下來(lái)前往父組件。
父組件監(jiān)聽(tīng)子組件彈射的事件
剛剛已經(jīng)在子組件設(shè)置好了暴露的變量,那么父組件如何接收呢?
常規(guī)的父組件調(diào)用子組件:
<app-child></app-child>
如果想監(jiān)聽(tīng)子組件的某個(gè)變量,可以使用圓括號(hào)():
<app-child (param1)="function1($event)"> </app-child>
$event 是Angular內(nèi)置的事件變量。
function1我們?cè)诟附M件中定義的處理變化的方法。
使用方式如下:
function1(param2: boolean) { // 這個(gè)param2為我們自己定義的參數(shù)名, // 本質(zhì)上是子組件中變化的param1參數(shù),但不用和子組件中的參數(shù)名相同 // 在此處增加處理過(guò)程即可 }
此時(shí),當(dāng)param1的值發(fā)生變化,就會(huì)執(zhí)行function1,并且傳入一個(gè)事件,事件的實(shí)質(zhì)內(nèi)容就是子組件定義的param1參數(shù)。
function1方法把參數(shù)作為param2接收,并添加處理過(guò)程。
五、總結(jié)
- Angular中,在HTML通過(guò)selector選擇器調(diào)用的組件稱(chēng)為子組件。
- 父組件向子組件傳值使用方括號(hào)[]
- 子組件有兩種方式接收值: @input + 變量名、@Input + set方法
- 子組件想父組件傳遞事件使用EventEmitter
- 父組件接收事件使用圓括號(hào)(),并聲明一個(gè)處理方法用來(lái)調(diào)用
熟悉的風(fēng)格,一圖勝千言:
六、后記
是不是有似曾相識(shí)的感覺(jué),在剛開(kāi)始接觸Angular時(shí)就知道,可以使用方括號(hào)[]來(lái)綁定原生HTML標(biāo)簽的某些屬性,例如:
<p [id]="sayHelloId" [style.color]="fontColor"> You can set my color in the component! </p>
另一方面,還有一個(gè)相似之處就是,Angular中也是使用圓括號(hào)()來(lái)綁定原生HTML標(biāo)簽的某個(gè)方法,例如:
<button (click)="onClick()"> 點(diǎn)我! </button>
這些是巧合嗎?并不是。
我們可以這樣理解:
Angular中所有的原生HTML標(biāo)簽都變成了組件。
之所以很多標(biāo)簽中可以用方括號(hào)[]綁定屬性、使用圓括號(hào)()綁定方法,是因?yàn)锳ngular已經(jīng)為我們擴(kuò)展了原生的HTML標(biāo)簽,使它們具備了接收和發(fā)送數(shù)據(jù)的能力!
換言之,在A(yíng)ngular內(nèi)部的組件中,已經(jīng)為我們加上了許許多多的@input和@output裝飾器,我們才能方便的綁定這些屬性和方法。
總結(jié)
到此這篇關(guān)于如何通過(guò)簡(jiǎn)單的代碼描述Angular父組件、子組件傳值的文章就介紹到這了,更多相關(guān)Angular父組件、子組件傳值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Webstorm 下的Angular2.0開(kāi)發(fā)之路(圖文)
這篇文章主要介紹了詳解Webstorm 下的Angular2.0開(kāi)發(fā)之路(圖文) ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12探索angularjs+requirejs全面實(shí)現(xiàn)按需加載的套路
這篇文章主要探索了angularjs+requirejs全面實(shí)現(xiàn)按需加載的套路,圍繞angularjs提供的各種機(jī)制進(jìn)行研究,感興趣的小伙伴們可以參考一下2016-02-02Angular4學(xué)習(xí)筆記router的簡(jiǎn)單使用
本篇文章主要介紹了Angular4學(xué)習(xí)筆記router的簡(jiǎn)單使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03ng-events類(lèi)似ionic中Events的angular全局事件
這篇文章主要介紹了ng-events類(lèi)似ionic中Events的angular全局事件,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09AngularJS 依賴(lài)注入詳解和簡(jiǎn)單實(shí)例
本文主要介紹AngularJS 依賴(lài)注入,這里對(duì)依賴(lài)注入做了詳細(xì)介紹講解,并提供效果圖和示例代碼以便學(xué)習(xí)參考2016-07-07Angular4學(xué)習(xí)筆記之根模塊與Ng模塊
這篇文章主要介紹了Angular4學(xué)習(xí)筆記之根模塊與Ng模塊,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09