您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Angular中組件樣式的工作原理是什么的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
在開發 Angular 組件的過程中,我們習慣把組件的樣式寫在對應的 css 文件中,但是一直不了解 Angular 是怎樣做到樣式隔離的,比如在 A 組件中寫了 h2 { color: red }
,這個樣式只會在 A 組件中生效,而不會影響到其他的組件。為了探究原理,就有了這篇文章,以下內容基于 Angular CLI 10.1.1 版本創建。
首先用 Angular CLI 創建一個新的 Angular 項目,刪除 app.component.html
中的所有內容,替換成如下內容:
<h2>App Component</h2> <button class="red-button">Button</button>
在 app.component.css
中添加如下內容:
.red-button { color: red; }
運行時有如下 html 代碼:
<app-root _nghost-ydo-c11="" ng-version="10.1.1"> <h3 _ngcontent-ydo-c11="">App component</h3> <button _ngcontent-ydo-c11="" class="red-button">Button</button> </app-root>
可以看到在在 app-root
元素上有一個名為 _nghost-ydo-c11
的屬性(property),app-root
里面的兩個元素都有一個名為 _ngcontent-ydo-c11
的屬性。
那么這些屬性是用來做什么的呢?
為了更好的理解,我們先創建一個獨立的組件,新建文件 blue-button.component.ts
,內容如下:
import { Component } from '@angular/core'; @Component({ selector: 'app-blue-button', template: ` <h3>Blue button component</h3> <button class="blue-button">Button</button> `, styles: [` .blue-button { background: blue; } `] }) export class BlueButtonComponent {}
放到 app.component.html
中運行后,會看到如下 html 代碼:
可以看到 app-blue-button
中也有一個以 _nghost-xxx
開頭的屬性,還有一個和 app-root
中其他元素相同的屬性。而在組件里面的兩個元素都有名為 _ngcontent-yke-c11
的屬性。
由于每次運行,Angular 生成的屬性字符串都是隨機的,所以后面的代碼如果出現了類似的屬性都是按照這個截圖對應的。
通過觀察我們可以總結出:
每個組件的宿主元素都會被分配一個唯一的屬性,具體取決于組件的處理順序,在例子中就是 _nghost_xxx
每個組件模板中的每個元素還會被分配一個該組件特有的屬性,在例子中就是 _ngcontent_xxx
那么這些屬性是怎樣用于樣式隔離的呢?
這些屬性可以和 CSS 結合起來,比如當我們查看例子中藍色按鈕的樣式時,會看到這樣的 css:
.blue-button[_ngcontent-yke-c11] { background: blue; }
可以看出,Angular 通過這種方式使 blue-button
類只能應用于有這個屬性的元素上,而不會影響到其他組件中的元素。
知道了 Angular 對樣式隔離的行為,那么 Angular 又是如何做到這些的呢?
在應用啟動時,Angular 將通過 styles 或 styleUrls 組件屬性來查看哪些樣式與哪些組件相關聯。之后Angular 會將這些樣式和該組件中元素特有的屬性應用到一起,將生成的 css 代碼包裹在一個 style 標簽中并放到 header 里。
以上就是 Angular 樣式封裝的原理。
在實際開發中,這種機制有時候并不能完全匹配我們的需求,針對這種情況, Angular 引入了幾種特殊的選擇器。
使用 :host 偽類選擇器,用來作用于組件(宿主元素)本身。
比如,當我們想給 app-blue-button
加個邊框時,可以在這個組件的樣式中添加如下代碼:
:host { display: block; border: 1px solid red; }
通過查看運行時的代碼,可以看到如下代碼塊:
<style> [_nghost-yke-c11] { display: block; border: 1px solid red; } </style>
有時候,基于某些來自組件視圖外部的條件應用樣式是很有用的。 例如,在文檔的 <body>
元素上可能有一個用于表示樣式主題 (theme) 的 CSS 類,你應當基于它來決定組件的樣式。
這時可以使用 :host-context()
偽類選擇器。它也以類似 :host()
形式使用。它在當前組件宿主元素的祖先節點中查找 CSS 類, 直到文檔的根節點為止。在與其它選擇器組合使用時,它非常有用。
在下面的例子中,會根據祖先元素的 CSS 類是 blue-theme
還是 red-theme
來決定哪個 CSS 會生效。
import { Component } from '@angular/core'; @Component({ selector: 'app-btn-theme', template: ` <button class="btn-theme">Button</button> `, styles: [` :host-context(.blue-theme) .btn-theme { background: blue; } :host-context(.red-theme) .btn-theme { background: red; } `] }) export class BtnThemeComponent { }
然后在使用的地方:
<div class="blue-theme"> <app-btn-theme></app-btn-theme> </div>
在運行的時候按鈕背景就是藍色的。
我們經常會使用一些第三方 UI 庫,有時候我們想改變第三方組件的一些樣式,這時候可以使用 ::ng-deep,但是要注意,Angular 已經把這個特性標記為已廢棄了,可能在未來的版本就被完全移除掉。
:host ::ng-deep h3 { color: yellow; }
通過查看運行時的代碼:
[_nghost-yke-c12] h3 { color: yellow; }
可以看到,樣式會作用在 app-root
里的所有元素上,包括 app-root
中使用的其他組件里的元素。
感謝各位的閱讀!關于“Angular中組件樣式的工作原理是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。