Angular樣式隔離(style isolation)及選擇器(:host, :host-context, ::ng-deep)的使用

来源:https://www.cnblogs.com/sparkler/archive/2022/11/27/16928600.html
-Advertisement-
Play Games

# HTTPS server server { listen 443; server_name ************.com; ssl on; ssl_certificate cert/************.com.pem; ssl_certificate_key cert/******** ...


1.Angular樣式隔離

Angular樣式隔離的好處最最要的一條就是CSS的可維護性。當沒有樣式隔離時,我們創建一個組件並添加樣式後,可能會影響到其他的組件樣式,而且很有可能查找不出問題所在。雖然我們可以想出辦法來避免樣式被覆蓋,但是可能會引發CSS的可維護性問題。

Angular的視圖封裝(View Encapsulation)

在Angular中,組件的樣式可以封裝在組件的宿主元素中(host),這樣它們就不會影響應用程式的其他部分。

視圖封裝模式:

1.ViewEncapsulation.ShadowDom: Angualr使用瀏覽器內置的Shadow Dom API將組件的視圖封裝在ShadowRoot中,用作組件的宿主元素,並以隔離的方式應用提供的樣式(只對瀏覽器內置Shadow Dom支持時才起作用)。組件的樣式只添加到Shadow Dom宿主中,確保它們隻影響各自組件視圖中的元素。

2.ViewEncapsulation.Emulated:使樣式僅應用於組件的視圖,不會影響應用程式中的其他元素,模擬Shadow Dom行為(預設的視圖封裝模式)。組件的樣式被添加到文檔的<head>中,使它們在整個應用程式中可用,但隻影響它們各自組件模板中的元素。

3.ViewEncapsulation.None:不使用任何類型的視圖封裝,為組件指定的任何樣式都是全局應用的,並且影響應用程式中的任何HTML元素。組建的樣式被添加到文檔的<head>中,使它們在整個應用程式中可用,所以時完全全局的,並影響文檔中的任務匹配元素。

要想設置組件的視圖封裝模式,可以在組件裝飾器中設置 encapsulation 選項。

為了更好的理解預設的視圖封裝(Emulated View Encapsulation)是如何起作用的,先貼上一段代碼:

 1 @Component({
 2     selector: 'app-root',
 3     template: `
 4         <h2>Parent Component</h2>
 5         <app-child></app-child>
 6     `,
 7     styles: [
 8         `
 9           h2 {
10             background-color: lightskyblue;
11           }
12         `
13     ],
14     encapsulation: ViewEncapsulation.Emulated
15 })    
16 export class AppComponent implements OnInit {
17    
18     ...
19 }
 1 @Component({
 2     selector: 'app-child',
 3     template: `
 4        <h2>Child Component</h2>
 5     `,
 6     styles: [
 7         `
 8           h2 {
 9             background-color: aqua;
10           }
11         `
12     ],
13     encapsulation: ViewEncapsulation.Emulated
14 })    
15 export class ChildComponent implements OnInit {
16    
17     ...
18 }

以下是運行時的代碼,

 可以看到app-root自定義元素上添加了一個奇怪的屬性:_nghost-jtq-c16屬性;在根組件中的HTML元素有一個看起來很奇怪但不同的屬性:_ngcontent-jtq-c16;app-child自定義元素上添加了另一個屬性:_nghost-jtq-c17,以及組件內HTML元素有一個_ngcontent-jtq-c17屬性。

因此,我們可以知道Angular樣式隔離的基本原理:

1.在應用程式啟動時(或在使用AOT構建時),每個組件都將具有附加到宿主元素的唯一屬性,具體取決於組件的處理順序:_nghost-jtq-c16, _nghost-jtq-c17。

2.除此之外,每個組件模板中的每個元素也將應用該特定組件獨有的屬性:_ngcontent-jtq-c16, _ngcontent-jtq-c17。

 Angular將這些樣式應用到相應的獨特屬性上:

2.選擇器(:host, :host-context, ::ng-deep)的使用

:host

每個組件都與一個和組件的選擇器相匹配的元素相關聯。呈現模板的這個元素稱為宿主元素。:host 偽類選擇器用於創建以宿主元素本身為目標的樣式,而不是以宿主內部的元素為目標。

當我們想要為app-root組件本身添加樣式(加一個邊框),就需要用到 :host 偽類選擇器,原因是所有與組件關聯的樣式(通過css文件或內聯形式在組件裝飾器中聲明),通常作用於模板內的元素。

1 :host {
2     display: block;
3     border: 5px solid palegreen;
4 }

 

 應用樣式後,組件顯示入下:

 :host與其他選擇器組合使用

1 :host h2 {
2     color: red;
3 }

 

1 :host(.active) {
2   font-weight: bold;
3 }

 在:host()選擇器中,括弧內的條件決定了要設置樣式的宿主元素(宿主元素具有active類)。

::ng-deep

將::ng-deep偽類應用於任何CSS規則會完全禁止視圖封裝規則;任何應用了::ng-deep的樣式都會成為全局樣式。為了將指定樣式限定在當前組件以及後代,確保在::ng-deep之前包含:host選擇器。如果在沒有:host偽類選擇器的情況下使用::ng-deep選擇器,樣式可能會滲入其他組件。

如果希望組件的樣式級聯到組件的所有子元素,而不是頁面上的任務其他元素,我們可以通過將:host與::ng-deep選擇器結合使用來實現:

1 :host ::ng-deep h2 {
2     color: red;
3 }

運行時生成如下樣式:

1 <style>  
2 [_nghost-c0]  h2 {
3     color: red;
4 }
5 </style>

此樣式將應用於app-root內所有h2元素。

這種選擇器的組合很有用,當將樣式應用到使用ng-content傳遞給模板的元素。

:host-context

根據宿主元素的祖先元素的某些條件,將樣式應用於組件模板中的元素,這時:host-context會很有用。

註:只有宿主元素及其後代會受到樣式影響,而不是祖先元素。

 1 @Component({
 2   selector: 'themeable-button',
 3   template: `
 4         <button class="btn btn-theme">Themeable Button</button>
 5   `,
 6   styles: [`
 7       :host-context(.red-theme) .btn-theme {
 8         background: red;
 9       }
10       :host-context(.blue-theme) .btn-theme {
11           background: blue;
12       }
13   `]
14 })
15 export class ThemeableButtonComponent {
16 
17 }

現在的樣式是不起作用的;為了使樣式生效,需要向該組件的任何父元素添加一個主題激活類。

1 <div class="blue-theme">
2     <themeable-button></themeable-button>
3 </div>

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、併發與競爭簡介 併發:多個“用戶”同時訪問一個共用的記憶體。 競爭:多個“用戶”同時訪問一段共用的記憶體並對其修改,就會造成數據混亂,甚至程式崩潰,這就是競爭。 二、造成併發與競爭的原因 1、多線程併發訪問, Linux 是多任務(線程)的系統,所以多線程訪問是最基本的原因。 2、搶占式併發訪問, ...
  • Systemd為Linux中的初始化init系統,用於啟動與停止服務進程,設計目標為:儘可能啟動更少進程、更多進程並行啟動;Systemd使用Linux的CGroup特性用來跟蹤與管理進程的生命周期,在服務啟動時會併發創建依賴的服務進程,子進程繼承父進程CGroup相關服務進程歸屬與同一個CGrou ...
  • 大數據時代,無人不知Google的“三駕馬車”。“三駕馬車”指的是Google發佈的三篇論文,介紹了Google在大規模數據存儲與計算方向的工程實踐,奠定了業界大規模分散式存儲系統的理論基礎,如今市場上流行的幾款國產資料庫都有參考這三篇論文。 《The Google File System》,200 ...
  • 騰訊雲資料庫在助力金融核心系統分散式替換上,已經輻射到了東南亞市場。 東南亞最大的銀行之一印尼BNC銀行(Bank Neo Commerce)已正式完成新核心分散式遷移,使用騰訊雲資料庫TDSQL後,系統運行平穩順暢。這標志著騰訊雲資料庫在經過國內多家大型核心系統的落地實踐後,開始走向海外,“技術出 ...
  • 華為開發者大會2022(HDC)上,HMS Core手語數字人以全新形象亮相,併在直播中完成了長達3個多小時的實時手語翻譯,向線上線下超過一千萬的觀眾提供了專業、實時、準確的手語翻譯服務,為聽障人士提供了無障礙參會體驗。面對專業性強且辭彙量大的科技大會,HMS Core手語數字人是如何準確且流暢地打 ...
  • 實現效果圖 GitHub 和 Gitee 個人主頁中可以對自己的項目進行拖拽排序,於是我就想自己實現一個。本隨筆只是記錄一下大概的實現思路,如果感興趣的小伙伴可以通過代碼和本隨筆的說明去理解實現過程。👉我的 Gitee 和 GitHub 地址。 線上瀏覽地址:11.拖拽排序,裡面還有更多的例子。 ...
  • 事情緣由 作為選修了移動互聯網應用的一員,老師講的什麼JS基礎,還有ES6和uniapp,當然是沒怎麼聽,因為是之前大二的時候都大概看過。 但是快到期末,老師講了雲開發,並且佈置了與此相關的大作業,自己做一個新聞資訊app,和一個小組作業,也是一個app,題目自擬,我對它來了興趣(bushi)。 初 ...
  • 最近在維護一個小後臺項目,有段JS需要壓縮上傳到CDN存儲伺服器。由於之前壓縮的JS文件都比較少,都是手動壓縮的。這次需要壓縮的文件比較多,所以用了批量壓縮。特此記錄一下,方便大家和自己以後再用到的時候備忘。 v準備工作 安裝nodejs 首先在本地安裝node.js和npm,一般npm集成於nod ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...