ホームページ  >  記事  >  ウェブフロントエンド  >  Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

青灯夜游
青灯夜游転載
2022-07-22 19:51:572808ブラウズ

Angularビューをカプセル化するにはどうすればよいですか?次の記事では、Angular Encapsulation の 3 つの方法について詳しく説明します。お役に立てば幸いです。

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

日常業務では、Component を定義するときに、その encapsulation カプセル化、つまり、必要かどうかを考慮する必要があります。このコンポーネントで定義されたスタイルをこのコンポーネントにのみ適用するか、グローバルに適用するか。 Angular では、コンポーネントのスタイルをコンポーネントのホスト要素内にカプセル化して、アプリケーションの残りの部分に影響を与えないようにすることができます。 Component デコレーターは、ビューのカプセル化をコンポーネントごとに適用する方法を制御するために使用できる encapsulation オプションを提供します。 [関連チュートリアルの推奨事項: "angular チュートリアル"]

ViewEncapsulation

Angular には、ViewEncapsulation.ShadowDom と ViewEncapsulation という 3 つのカプセル化モードがあります。エミュレート、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: シムされた CSS を使用してネイティブの動作をエミュレートします。
  • ViewEncapsulation.None: カプセル化せずにグローバル CSS を使用します。
  • ViewEncapsulation.ShadowDom: Shadow DOM v1 を使用してスタイルをカプセル化します。

指定しない場合、値は CompilerOptions から取得されます。デフォルトのコンパイラ オプションは ViewEncapsulation.Emulated です。

ポリシーが ViewEncapsulation.Emulated に設定されており、コンポーネントでスタイルまたは styleUrls が指定されていない場合、自動的に ViewEncapsulation.None に切り替わります。

列挙型は見つかりましたか? 1 がないのはなぜですか?これについては後で詳しく説明します。

ViewEncapsulation.ShadowDom

Angular での ShadowDom のカプセル化はさておき、まず ShadowDOM とは何かを見てみましょう。

Shadow DOM

Shadow DOM を使用すると、非表示の DOM ツリーを通常の DOM ツリーに接続できます - それはシャドウ ルート ノードから始まります。通常の DOM 要素と同様に、任意の要素を指定できます。

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

ここで、理解する必要がある Shadow DOM 固有の用語がいくつかあります。

  • シャドウ ホスト: シャドウが接続される通常の DOM ノード。 DOM はこのノードに接続されます。
  • Shadow ツリー: Shadow DOM 内の DOM ツリー。
  • シャドウ境界: Shadow DOM が終了し、通常の DOM が始まる場所。
  • シャドウ ルート: シャドウ ツリーのルート ノード。

Shadow DOM は、子ノードの追加、プロパティの設定、ノードへの独自のスタイルの追加など、通常の DOM と同じ方法で操作できます (たとえば、element.style を使用)。 property ) を使用するか、Shadow DOM 全体にスタイルを追加します ( 要素内にスタイルを追加するなど)。違いは、Shadow DOM 内の要素が Shadow DOM の外側の要素に決して影響を与えないことです (:focus-within を除く)。これにより、カプセル化が容易になります。

簡単な例を見てみましょう。

nbsp;html>


    <meta>
    <meta>
    <meta>
    <title>Shadow DOM</title>
    <style>
        span{
            color: green;
        }
    </style>


    <span>我是Root</span>
    <div></div>
    <script>
        let app = document.querySelector(&#39;#app&#39;);
        let shadow1 = app.attachShadow({ mode: &#39;open&#39;});
        
        let style1 = document.createElement(&#39;style&#39;);
        style1.appendChild(document.createTextNode("span{color: red;}"));
        shadow1.appendChild(style1);

        let span1 = document.createElement(&#39;span&#39;);
        span1.textContent = &#39;I am span.&#39;;
        shadow1.appendChild(span1);
    </script>

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

上記の例では、グローバルなスパンスタイルを定義し、shadowDOMにもスパンスタイルを定義していますが、相互に影響を受けていないことがわかります。

Angular での ShadowDOM のカプセル化

ShadowDOM とは何かを理解した後、Angular での ShadowDOM のカプセル化を見てみましょう。

Angular 使用浏览器内置的 Shadow DOM API 将组件的视图包含在 ShadowRoot(用作组件的宿主元素)中,并以隔离的方式应用所提供的样式。ViewEncapsulation.ShadowDom 仅适用于内置支持 shadow DOM 的浏览器。并非所有浏览器都支持它,这就是为什么 ViewEncapsulation.Emulated 是推荐和默认模式的原因。

比如下面的这个例子,使用ViewEncapsulation.ShadowDom

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

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

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

从运行的页面上看到,user-child组件内部被封装成了一个ShadowDOM,style也被封装在了里面,并不会对外部的样式造成影响。

ViewEncapsulation.Emulated

Angular 会修改组件的 CSS 选择器,使它们只应用于组件的视图,不影响应用程序中的其他元素(模拟 Shadow DOM 行为)。

使用模拟视图封装时,Angular 会预处理所有组件的样式,以便它们仅应用于组件的视图。在正运行的 Angular 应用程序的 DOM 中,使用模拟视图封装模式的组件所在的元素附加了一些额外的属性:

<hero-details>
  <h3>Mister Fantastic</h3>
  <hero-team>
    <h4>Team</h4>
  </hero-team>
</hero-details>

有两种这样的属性:

属性 详情
_nghost 被添加到包裹组件视图的元素中,这将是本机 Shadow DOM 封装中的 ShadowRoots。组件的宿主元素通常就是这种情况
_ngcontent 被添加到组件视图中的子元素上,这些属性用于将元素与其各自模拟的 ShadowRoots(具有匹配 _nghost 属性的宿主元素)相匹配。

这些属性的确切值是 Angular 的私有实现细节。它们是自动生成的,你不应在应用程序代码中引用它们。

它们以生成的组件样式为目标,这些样式会被注入到 DOM 的  部分:

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

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

这些样式经过后期处理,以便每个 CSS 选择器都使用适当的 _nghost 或 _ngcontent 属性进行扩充。这些修改后的选择器可以确保样式以隔离和有针对性的方式应用于组件的视图。

<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 はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

ViewEncapsulation.Emulated 设置的结果是没有 Shadow DOM,但是通过 Angular 提供的样式包装机制来封装组件,使得组件的样式不受外部影响。虽然样式仍然是应用到整个 document,但 Angular 为 p创建了一个 [_ngcontent-oow-c11] 选择器。可以看出,我们为组件定义的样式,被 Angular 修改了。简单来说,尽管是也是全局样式,但是由于自动选择器的原因,并不会影响其他组件的样式。如果手动在其他元素上也添加这个属性,则样式也会应用到这元素上。

ViewEncapsulation.None

Angular 不应用任何形式的视图封装,这意味着为组件指定的任何样式实际上都是全局应用的,并且可以影响应用程序中存在的任何 HTML 元素。这种模式本质上与将样式包含在 HTML 本身中是一样的。

parent:

<p>parent works!{{count}}</p>
<p>第一个:{{count}}</p>
<span>parent</span>
<app-child></app-child>

child:

    <p>child works!</p>     Child
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 はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

被废弃的Native

在Angular2中使用ViewEncapsulation.Native。

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

Angular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょう

ViewEncapsulation.Native 设置的结果是使用原生的 Shadow DOM 特性。Angular 会把组件按照浏览器支持的 Shadow DOM 形式渲染。其实这种就是后来的ViewEncapsulation.ShadowDom

总结

我们介绍了Angular视图封装的三种方式,各自的特点,日常工作中要根据特定的场景去选择哪种封装方式。

更多编程相关知识,请访问:编程视频!!

以上がAngular はビューのカプセル化をどのように実装しますか? 3 つのパッケージング モードについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。