Angular - 檢視封裝



檢視封裝是一種將給定檢視的樣式與應用程式的其他部分封裝的技術。一般來說,應用於 HTML 文件的 CSS 樣式會影響整個文件。Angular 框架也同樣適用。這種預設行為在某些情況下(例如全域性樣式)是有利的,但同時它也可能無意中影響應用程式的特定部分(例如具有特定樣式的特殊按鈕/連結)。為了確保應用程式特定部分的樣式不會受到影響,可以使用 Angular 提供的檢視封裝概念。

選項

Angular 在元件裝飾器中提供了一個屬性 `encapsulation` 來指導如何保護元件樣式。`encapsulation` 的選項如下:

  • None (ViewEncapsulation.None)

  • Emulated (ViewEncapsulation.Emulated)

  • ShadowDom (ViewEncapsulation.ShadowDom)

None

None 選項不會對保護元件內元素的樣式做任何事情。元件檢視將暴露於所有全域性樣式並受其影響。

讓我們建立一個簡單的元件,並檢查元件檢視是如何生成和渲染的。

步驟1:建立一個新元件,`view-encapsulation-sample`

$ ng generate component view-encapsulation-sample
CREATE src/app/view-encapsulation-sample/view-encapsulation-sample.component.css (0 bytes)
CREATE src/app/view-encapsulation-sample/view-encapsulation-sample.component.html (40 bytes)
CREATE src/app/view-encapsulation-sample/view-encapsulation-sample.component.spec.ts (680 bytes)
CREATE src/app/view-encapsulation-sample/view-encapsulation-sample.component.ts (276 bytes)
UPDATE src/app/app.module.ts (547 bytes)

步驟2:在元件中新增 None 檢視封裝,如下所示:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
   selector: 'app-view-encapsulation-sample',
   templateUrl: './view-encapsulation-sample.component.html',
   styleUrls: ['./view-encapsulation-sample.component.css'],
   encapsulation: ViewEncapsulation.None
})
export class ViewEncapsulationSampleComponent {

}

步驟3:更改模板 `view-encapsulation-sample.component.html` 並新增兩個容器,如下所示:

<div>I am inside the none container</div>
<div class="mystyle">I am inside the none container and has my own style</div>

這裡,第一個容器沒有任何樣式或類,更容易受到全域性樣式的影響。第二個容器具有類屬性,但仍然有可能受到全域性樣式的影響。

步驟4:在元件 CSS 檔案 `view-encapsulation-sample.component.css` 中應用樣式,如下所示:

div.mystyle { color: brown }

步驟5:將元件新增到應用程式元件 `app.component.html` 中,如下所示:

<app-view-encapsulation-sample />

<router-outlet></router-outlet>

步驟6:執行應用程式並檢查生成的 HTML 和 CSS

<app-view-encapsulation-sample _ngcontent-ng-c750168442="">
   <div>I am inside the none container</div>
   <div class="mystyle">I am inside the none container and has my own style</div>
</app-view-encapsulation-sample>
div.mystyle {
   color: brown;
}

在這裡,您可以清楚地看到生成的樣式和元素是普通的,沒有應用任何保護措施,應用程式的外觀如下所示:

步驟7:在我們的全域性 CSS 資產 `styles.css` 中新增一個針對 div 標籤的樣式,然後重新執行應用程式

div { color: blue }

現在,第一個容器的顏色變為藍色,如下所示:

Emulated

Emulated 選項將更改樣式,使其僅應用於元件內的元素。元件的元素在任何情況下都不會受到全域性樣式的影響。

讓我們更改我們的應用程式並應用 Emulated 選項,如下所示:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
   selector: 'app-view-encapsulation-sample',
   templateUrl: './view-encapsulation-sample.component.html',
   styleUrls: ['./view-encapsulation-sample.component.css'],
   encapsulation: ViewEncapsulation.Emulated
})
export class ViewEncapsulationSampleComponent {
}

現在,重新執行應用程式並檢查輸出。

<app-view-encapsulation-sample _ngcontent-ng-c750168442="" _nghost-ng-c2076704321="">
   <div _ngcontent-ng-c2076704321="">I am inside the none container</div>
   <div _ngcontent-ng-c2076704321="" class="mystyle">I am inside the none container and has my own style</div>
</app-view-encapsulation-sample>
div.mystyle[_ngcontent-ng-c2076704321] {
   color: brown;
}

現在,容器透過使用 Angular 生成的特殊屬性(_ngcontent-ng-c2076704321)應用樣式來保護,並且 CSS 不受全域性樣式的影響。

ShadowDom

ShadowDom 選項將應用 HTML 原生的 shadow dom 概念來保護元件的樣式。元件的元素在任何情況下都不會受到全域性樣式的影響,因為它完全隱藏了 shadowDOM 概念。

更改我們的應用程式並應用 ShadowDOM 選項,如下所示:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
   selector: 'app-view-encapsulation-sample',
   templateUrl: './view-encapsulation-sample.component.html',
   styleUrls: ['./view-encapsulation-sample.component.css'],
   encapsulation: ViewEncapsulation.ShadowDom
})
export class ViewEncapsulationSampleComponent {

}

現在,重新執行應用程式並檢查輸出。

shadowdom

現在,兩個容器都受到原生 shadowDOM 概念的保護,並且不受全域性樣式的影響。

在應用程式中應用不同的封裝

元件的檢視封裝可以與應用程式中使用的其他元件不同,因為檢視封裝是基於每個元件應用的。即使是巢狀元件也可以根據元件需求具有不同的檢視封裝選項。Angular 甚至在非常複雜的巢狀元件樹中也會根據指示應用封裝。

廣告