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