W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在 Angular 中,組件的樣式可以封裝在組件的宿主元素中,這樣它們就不會(huì)影響應(yīng)用程序的其余部分。
?Component
?的裝飾器提供了 ?encapsulation
?選項(xiàng),可用來(lái)控制如何基于每個(gè)組件應(yīng)用視圖封裝。
從以下模式中選擇:
ViewEncapsulation.ShadowDom
? ,Angular 使用瀏覽器內(nèi)置的 Shadow DOM API 將組件的視圖包含在 ShadowRoot(用作組件的宿主元素)中,并以隔離的方式應(yīng)用所提供的樣式。
ViewEncapsulation.Emulated
?,Angular 會(huì)修改組件的 CSS 選擇器,使它們只應(yīng)用于組件的視圖,不影響應(yīng)用程序中的其他元素(模擬 Shadow DOM 行為)。ViewEncapsulation.None
? ,Angular 不應(yīng)用任何形式的視圖封裝,這意味著為組件指定的任何樣式實(shí)際上都是全局應(yīng)用的,并且可以影響應(yīng)用程序中存在的任何 HTML 元素。這種模式本質(zhì)上與將樣式包含在 HTML 本身中是一樣的。?
ViewEncapsulation.ShadowDom
? 僅適用于內(nèi)置支持 shadow DOM 的瀏覽器(請(qǐng)參閱 Can I use - Shadow DOM v1 )。并非所有瀏覽器都支持它,這就是為什么 ?ViewEncapsulation.Emulated
? 是推薦和默認(rèn)模式的原因。
使用模擬視圖封裝時(shí),Angular 會(huì)預(yù)處理所有組件的樣式,以便它們僅應(yīng)用于組件的視圖。
在正運(yùn)行的 Angular 應(yīng)用程序的 DOM 中,使用模擬視圖封裝模式的組件所在的元素附加了一些額外的屬性:
<hero-details _nghost-pmm-5>
<h2 _ngcontent-pmm-5>Mister Fantastic</h2>
<hero-team _ngcontent-pmm-5 _nghost-pmm-6>
<h3 _ngcontent-pmm-6>Team</h3>
</hero-team>
</hero-detail>
有兩種這樣的屬性:
_nghost
? 屬性被添加到包裹組件視圖的元素中,這將是本機(jī) Shadow DOM 封裝中的 ShadowRoots。組件的宿主元素通常就是這種情況。
_ngcontent
? 屬性被添加到組件視圖中的子元素上,這些屬性用于將元素與其各自模擬的 ShadowRoots(具有匹配 ?_nghost
? 屬性的宿主元素)相匹配。這些屬性的確切值是 Angular 的私有實(shí)現(xiàn)細(xì)節(jié)。它們是自動(dòng)生成的,你不應(yīng)在應(yīng)用程序代碼中引用它們。
它們以生成的組件樣式為目標(biāo),這些樣式會(huì)被注入到 DOM 的 ?<head>
? 部分:
[_nghost-pmm-5] {
display: block;
border: 1px solid black;
}
h3[_ngcontent-pmm-6] {
background-color: white;
border: 1px solid #777;
}
這些樣式經(jīng)過(guò)后期處理,以便每個(gè) CSS 選擇器都使用適當(dāng)?shù)?nbsp;?_nghost
? 或 ?_ngcontent
? 屬性進(jìn)行擴(kuò)充。這些修改后的選擇器可以確保樣式以隔離和有針對(duì)性的方式應(yīng)用于組件的視圖。
如前所述,你可以在組件的裝飾器中針對(duì)每個(gè)組件指定封裝模式,這意味著在你的應(yīng)用程序中,不同的組件可以使用不同的封裝策略。
盡管可能,但不建議這樣做。如果真的需要,你應(yīng)該知道使用不同封裝模式的組件的樣式會(huì)如何彼此交互:
ViewEncapsulation.Emulated
? 的組件樣式會(huì)添加到文檔的 ?<head>
? 中,使它們?cè)谡麄€(gè)應(yīng)用程序中可用,但它們的選擇器只會(huì)影響它們各自組件模板中的元素。
ViewEncapsulation.None
? 的組件樣式會(huì)添加到文檔的 ?<head>
? 中,使它們?cè)谡麄€(gè)應(yīng)用程序中可用,因此是完全全局的,會(huì)影響文檔中的任何匹配元素。
ViewEncapsulation.ShadowDom
? 的組件樣式僅添加到 shadow DOM 宿主中,確保它們僅影響各自組件視圖中的元素。?ViewEncapsulation.Emulated
? 和 ?ViewEncapsulation.None
? 組件的樣式也會(huì)添加到每個(gè) ?ViewEncapsulation.ShadowDom
? 組件的 shadow DOM 宿主中。
這意味著帶有 ?ViewEncapsulation.None
? 的組件的樣式將影響 shadow DOM 中的匹配元素。
這種方法乍一看似乎有違直覺,但如果沒有它,帶有 ?ViewEncapsulation.None
? 的組件將在使用 ?ViewEncapsulation.ShadowDom
? 的組件內(nèi)呈現(xiàn)不同的效果,因?yàn)槠錁邮綄⒉豢捎谩?/blockquote>例子
本節(jié)展示了具有不同 ?
ViewEncapsulation
?的組件的樣式如何交互的示例。請(qǐng)參閱 現(xiàn)場(chǎng)演練 以自己嘗試這些組件。
無(wú)封裝
第一個(gè)示例顯示了一個(gè)具有 ?
ViewEncapsulation.None
? 的組件。此組件將其模板元素著色為紅色。
@Component({ selector: 'app-no-encapsulation', template: ` <h2>None</h2> <div class="none-message">No encapsulation</div> `, styles: ['h2, .none-message { color: red; }'], encapsulation: ViewEncapsulation.None, }) export class NoEncapsulationComponent { }
Angular 將此組件的樣式作為全局樣式添加到文檔的 ?
<head>
? 中。如前所述,Angular 還會(huì)將這些樣式添加到所有 shadow DOM 宿主。因此,樣式在整個(gè)應(yīng)用程序中都可用。
模擬封裝
第二個(gè)示例顯示了一個(gè)具有 ?
ViewEncapsulation.Emulated
? 的組件。此組件將其模板元素著色為綠色。
@Component({ selector: 'app-emulated-encapsulation', template: ` <h2>Emulated</h2> <div class="emulated-message">Emulated encapsulation</div> <app-no-encapsulation></app-no-encapsulation> `, styles: ['h2, .emulated-message { color: green; }'], encapsulation: ViewEncapsulation.Emulated, }) export class EmulatedEncapsulationComponent { }
與 ?
ViewEncapsulation.None
? 類似,Angular 會(huì)將此組件的樣式添加到文檔的 ?<head>
? 中,但它們是帶有“作用域”的樣式。因此,只有直接在該組件模板中的元素才會(huì)匹配其樣式。由于來(lái)自 ?
EmulatedEncapsulationComponent
?的樣式是非常特化的,因此它們會(huì)覆蓋來(lái)自 ?NoEncapsulationComponent
?的全局樣式。在此示例中,?
EmulatedEncapsulationComponent
?包含著 ?NoEncapsulationComponent
?, 但 ?NoEncapsulationComponent
?仍然如預(yù)期般生效了,因?yàn)?nbsp;?EmulatedEncapsulationComponent
?的“范圍化”樣式與其模板中的元素并不匹配。
Shadow DOM 封裝
第三個(gè)示例顯示了一個(gè)具有 ?
ViewEncapsulation.ShadowDom
? 的組件。此組件會(huì)將其模板元素著色為藍(lán)色。
@Component({ selector: 'app-shadow-dom-encapsulation', template: ` <h2>ShadowDom</h2> <div class="shadow-message">Shadow DOM encapsulation</div> <app-emulated-encapsulation></app-emulated-encapsulation> <app-no-encapsulation></app-no-encapsulation> `, styles: ['h2, .shadow-message { color: blue; }'], encapsulation: ViewEncapsulation.ShadowDom, }) export class ShadowDomEncapsulationComponent { }
Angular 僅將此組件的樣式添加到 shadow DOM 宿主,因此它們?cè)?nbsp;shadow DOM 之外是不可見的。
請(qǐng)注意,Angular 還將 ?
NoEncapsulationComponent
?和 ?ViewEncapsulationComponent
?的全局樣式添加到了 shadow DOM 宿主中,因此這些樣式仍然可用于該組件的模板中的元素。在這個(gè)例子中, ?
ShadowDomEncapsulationComponent
?包含一個(gè) ?NoEncapsulationComponent
?和 ?ViewEncapsulationComponent
?。?
ShadowDomEncapsulationComponent
?組件添加的樣式在該組件的整個(gè) shadow DOM 中都可用,在 ?NoEncapsulationComponent
?和 ?ViewEncapsulationComponent
?中也是如此。?
EmulatedEncapsulationComponent
?具有特化的“范圍化”樣式,因此該組件模板的樣式不受影響。但是由于 ?
ShadowDomEncapsulationComponent
?中的樣式是在全局樣式之后添加到 Shadow Host 中的,因此 ?h2
?樣式會(huì)覆蓋 ?NoEncapsulationComponent
?中的樣式。結(jié)果是 ?NoEncapsulationComponent
?中的 ?<h2>
? 元素被著色為藍(lán)色而不是紅色,這可能不是組件作者的本意。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: