1. 程式人生 > >Angular父組件內修改子組件的樣式

Angular父組件內修改子組件的樣式

src 投影 然而 angular amp mage 找不到 com 需要

問題的產生與描述

在使用NG-ZORRO組件的過程中,需要根據產品的需要,在某些頁面修改某些NZ組件的樣式。但是由於angular默認采用了Emulated的視圖封裝模式,導致即便我們想在父組件中直接去重寫子組件的樣式,也無法辦到。

例如AppComponent是一個"父組件",其內包含Comp1Component與Comp2Component兩個"子組件"。即使我在AppComponent中添加樣式如下樣式,然而組件1的字體顏色依然沒有變成紅色。設置在控制臺選中組件1,styles中根本沒有對應的樣式。

.f-red{
    color: red;
}

/* 企圖修改組件1的字體顏色 */
#comp1{
    color: red;
}

技術分享圖片

問題分析

angular組件的CSS樣式被封裝進了自己的視圖中,而不會影響到應用程序的其它組件,這個效果在大部分時候非常的有用,我們不用擔心某個組件的代碼會汙染其子組件,但當我們想改變第三方庫的樣式的時候也非常的麻煩。angular的視圖封裝模式默認是Emulated 模式,以下是官方對其功能的描述。

通過預處理(並改名)CSS 代碼來模擬 Shadow DOM 的行為,以達到把 CSS 樣式局限在組件視圖中的目的。

其實如果在html中搜索#comp1,會得到如下的結果。angular默認的為每個組件添加了一個屬性,同樣也為css限定了對應的屬性。這也是為什麽在"父組件"修改"子組件"不生效,因為根本找不到#comp1[_ngcontent-haw-c0]

選擇器對應的元素。

技術分享圖片

解決辦法

可以使用 /deep/>>>::ng-deep選擇器來強制一個樣式對各級子組件的視圖也生效,它不但會作用於組件的子視圖,也會作用於投影進來的內容(ng-content)。

.f-red{
    color: red;
}

/* 企圖修改組件1的字體顏色 */
/* :host ::ng-deep #comp1{
    color: red;
} */
:host /deep/ #comp1{
    color: red;
}

技術分享圖片

需要註意的是CSS標準中用於"刺穿 Shadow DOM"的組合器已經被廢棄,並將這個特性從主流瀏覽器和工具中移除。angular官方建議統一使用 ::ng-deep,以便兼容將來的工具。

Angular父組件內修改子組件的樣式