Angular怎么進(jìn)行視圖封裝

本篇內(nèi)容主要講解“Angular怎么進(jìn)行視圖封裝”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Angular怎么進(jìn)行視圖封裝”吧!

成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)10余年經(jīng)驗成就非凡,專業(yè)從事成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè),成都網(wǎng)頁設(shè)計,成都網(wǎng)頁制作,軟文營銷1元廣告等。10余年來已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:13518219792,我們期待您的來電!

Angular怎么進(jìn)行視圖封裝

在日常工作中,當(dāng)我們定義一個Component的時候,要考慮它的encapsulation封裝性,也就是說你期望這個組件里定義的樣式是只作用于這個組件,還是想作用于全局。在 Angular 中,組件的樣式可以封裝在組件的宿主元素中,這樣它們就不會影響應(yīng)用程序的其余部分。Component 的裝飾器提供了 encapsulation 選項,可用來控制如何基于每個組件應(yīng)用視圖封裝。ViewEncapsulation

Angular中有三種封裝模式,分別是ViewEncapsulation.ShadowDom,ViewEncapsulation.Emulated,ViewEncapsulation.None。

export enum ViewEncapsulation {
    /**
     * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
     * component's host element and applying the same attribute to all the CSS selectors provided
     * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
     *
     * This is the default option.
     */
    Emulated = 0,
    /**
     * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
     * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
     * to any HTML element of the application regardless of their host Component.
     */
    None = 2,
    /**
     * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
     * a ShadowRoot for the component's host element which is then used to encapsulate
     * all the Component's styling.
     */
    ShadowDom = 3
}
  • ViewEncapsulation.Emulated:使用墊片(shimmed) CSS 來模擬原生行為。

  • ViewEncapsulation.None :使用不帶任何封裝的全局 CSS。

  • ViewEncapsulation.ShadowDom:使用 Shadow DOM v1,封裝樣式。

如果沒有提供,該值就會從 CompilerOptions 中獲取它。默認(rèn)的編譯器選項是 ViewEncapsulation.Emulated。

如果該策略設(shè)置為 ViewEncapsulation.Emulated,并且該組件沒有指定 styles 或 styleUrls,就會自動切換到 ViewEncapsulation.None。

有沒有發(fā)現(xiàn)枚舉類型了為什么沒有1?這個待會再說。

ViewEncapsulation.ShadowDom

拋開Angular中的ShadowDom的封裝,先來看一下什么是ShadowDOM吧。

Shadow DOM

Shadow DOM 允許將隱藏的 DOM 樹附加到常規(guī)的 DOM 樹中——它以 shadow root 節(jié)點為起始根節(jié)點,在這個根節(jié)點的下方,可以是任意元素,和普通的 DOM 元素一樣。

Angular怎么進(jìn)行視圖封裝

這里,有一些 Shadow DOM 特有的術(shù)語需要我們了解:

  • Shadow host:一個常規(guī) DOM 節(jié)點,Shadow DOM 會被附加到這個節(jié)點上。

  • Shadow tree:Shadow DOM 內(nèi)部的 DOM 樹。

  • Shadow boundary:Shadow DOM 結(jié)束的地方,也是常規(guī) DOM 開始的地方。

  • Shadow root: Shadow tree 的根節(jié)點。

你可以使用同樣的方式來操作 Shadow DOM,就和操作常規(guī) DOM 一樣——例如添加子節(jié)點、設(shè)置屬性,以及為節(jié)點添加自己的樣式(例如通過 element.style 屬性),或者為整個 Shadow DOM 添加樣式(例如在  元素內(nèi)添加樣式)。不同的是,Shadow DOM 內(nèi)部的元素始終不會影響到它外部的元素(除了 :focus-within),這為封裝提供了便利。

我們來看一個簡單的例子吧。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shadow DOM</title>
    <style>
        span{
            color: green;
        }
    </style>
</head>
<body>
    <span>我是Root</span>
    <div id="app"></div>
    <script>
        let app = document.querySelector('#app');
        let shadow1 = app.attachShadow({ mode: 'open'});
        
        let style1 = document.createElement('style');
        style1.appendChild(document.createTextNode("span{color: red;}"));
        shadow1.appendChild(style1);

        let span1 = document.createElement('span');
        span1.textContent = 'I am span.';
        shadow1.appendChild(span1);
    </script>
</body>
</html>

Angular怎么進(jìn)行視圖封裝

上面的例子,定義了全局span的樣式,也定義了shadowDOM里的span樣式,可以看出相互不受影響。

Angular中ShadowDOM的封裝

了解了什么是ShadowDOM后,再來看一下Angular中ShadowDOM的封裝。

Angular 使用瀏覽器內(nèi)置的 Shadow DOM API 將組件的視圖包含在 ShadowRoot(用作組件的宿主元素)中,并以隔離的方式應(yīng)用所提供的樣式。ViewEncapsulation.ShadowDom 僅適用于內(nèi)置支持 shadow DOM 的瀏覽器。并非所有瀏覽器都支持它,這就是為什么 ViewEncapsulation.Emulated 是推薦和默認(rèn)模式的原因。

比如下面的這個例子,使用ViewEncapsulation.ShadowDom

@Component({
  selector: 'user-child',
  templateUrl: 'UserChild.component.html',
  styles: [`
  h4{
    color: red;
  }
  `],
  encapsulation: ViewEncapsulation.ShadowDom
})

export class UserChildComponent implements OnInit {
  ......
}

Angular怎么進(jìn)行視圖封裝

從運行的頁面上看到,user-child組件內(nèi)部被封裝成了一個ShadowDOM,style也被封裝在了里面,并不會對外部的樣式造成影響。

ViewEncapsulation.Emulated

Angular 會修改組件的 CSS 選擇器,使它們只應(yīng)用于組件的視圖,不影響應(yīng)用程序中的其他元素(模擬 Shadow DOM 行為)。

使用模擬視圖封裝時,Angular 會預(yù)處理所有組件的樣式,以便它們僅應(yīng)用于組件的視圖。在正運行的 Angular 應(yīng)用程序的 DOM 中,使用模擬視圖封裝模式的組件所在的元素附加了一些額外的屬性:

<hero-details _nghost-pmm-5>
  <h4 _ngcontent-pmm-5>Mister Fantastic</h4>
  <hero-team _ngcontent-pmm-5 _nghost-pmm-6>
    <h5 _ngcontent-pmm-6>Team</h5>
  </hero-team>
</hero-details>

有兩種這樣的屬性:

屬性詳情
_nghost被添加到包裹組件視圖的元素中,這將是本機 Shadow DOM 封裝中的 ShadowRoots。組件的宿主元素通常就是這種情況。
_ngcontent被添加到組件視圖中的子元素上,這些屬性用于將元素與其各自模擬的 ShadowRoots(具有匹配 _nghost 屬性的宿主元素)相匹配。

這些屬性的確切值是 Angular 的私有實現(xiàn)細(xì)節(jié)。它們是自動生成的,你不應(yīng)在應(yīng)用程序代碼中引用它們。

它們以生成的組件樣式為目標(biāo),這些樣式會被注入到 DOM 的  部分:

[_nghost-pmm-5] {
  display: block;
  border: 1px solid black;
}

h5[_ngcontent-pmm-6] {
  background-color: white;
  border: 1px solid #777;
}

這些樣式經(jīng)過后期處理,以便每個 CSS 選擇器都使用適當(dāng)?shù)?_nghost 或 _ngcontent 屬性進(jìn)行擴(kuò)充。這些修改后的選擇器可以確保樣式以隔離和有針對性的方式應(yīng)用于組件的視圖。

<p>child works!</p>
p{
  color: green;
}
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
  encapsulation: ViewEncapsulation.Emulated
})
export class ChildComponent implements OnInit {
 ......
}

Angular怎么進(jìn)行視圖封裝

ViewEncapsulation.Emulated 設(shè)置的結(jié)果是沒有 Shadow DOM,但是通過 Angular 提供的樣式包裝機制來封裝組件,使得組件的樣式不受外部影響。雖然樣式仍然是應(yīng)用到整個 document,但 Angular 為 p創(chuàng)建了一個 [_ngcontent-oow-c11] 選擇器??梢钥闯觯覀?yōu)榻M件定義的樣式,被 Angular 修改了。簡單來說,盡管是也是全局樣式,但是由于自動選擇器的原因,并不會影響其他組件的樣式。如果手動在其他元素上也添加這個屬性,則樣式也會應(yīng)用到這元素上。

ViewEncapsulation.None

Angular 不應(yīng)用任何形式的視圖封裝,這意味著為組件指定的任何樣式實際上都是全局應(yīng)用的,并且可以影響應(yīng)用程序中存在的任何 HTML 元素。這種模式本質(zhì)上與將樣式包含在 HTML 本身中是一樣的。

parent:

<p #caption>parent works!{{count}}</p>
<p #caption>第一個:{{count}}</p>
<span class="red-font">parent</span>
<app-child></app-child>

child:

<div style="border: 1px solid green;">
    <p>child works!</p>
    <span class="red-font">Child</span>
</div>
p{
  color: green;
}
.red-font {
  color: red;
}
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ChildComponent implements OnInit {
  ......
}

Angular怎么進(jìn)行視圖封裝

被廢棄的Native

在Angular2中使用ViewEncapsulation.Native。

@Component({
  ...,
  encapsulation: ViewEncapsulation.Native
})
export class UserComponent {

Angular怎么進(jìn)行視圖封裝

ViewEncapsulation.Native 設(shè)置的結(jié)果是使用原生的 Shadow DOM 特性。Angular 會把組件按照瀏覽器支持的 Shadow DOM 形式渲染。其實這種就是后來的ViewEncapsulation.ShadowDom。

到此,相信大家對“Angular怎么進(jìn)行視圖封裝”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

名稱欄目:Angular怎么進(jìn)行視圖封裝
鏈接URL:http://muchs.cn/article46/pdphhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站排名、網(wǎng)站設(shè)計網(wǎng)站設(shè)計公司、用戶體驗企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化