Maison  >  Article  >  interface Web  >  Comment Angular implémente-t-il l'encapsulation des vues ? Parlons de trois modes de packaging

Comment Angular implémente-t-il l'encapsulation des vues ? Parlons de trois modes de packaging

青灯夜游
青灯夜游avant
2022-07-22 19:51:572808parcourir

AngularComment encapsuler des vues ? L'article suivant vous donnera une compréhension approfondie des trois méthodes d'encapsulation angulaire. J'espère qu'il vous sera utile !

Comment Angular implémente-t-il l'encapsulation des vues ? Parlons de trois modes de packaging

Dans le travail quotidien, lorsque l'on définit un Composant, il faut considérer son encapsulation encapsulation, c'est-à-dire, attendez-vous que les styles définis dans ce composant n'agissent que sur ce composant, ou est-ce que vous vouloir agir sur la situation mondiale. Dans Angular, les styles d'un composant peuvent être encapsulés dans l'élément hôte du composant afin qu'ils n'affectent pas le reste de l'application. Le décorateur Component fournit l'option encapsulation pour contrôler la façon dont l'encapsulation de la vue est appliquée pour chaque composant. [Recommandations de didacticiel associées : "Tutoriel angulaire"]

ViewEncapsulation

Il existe trois modes d'encapsulation dans Angular, à savoir ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated et 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 : utilisez du CSS shimed pour émuler le comportement natif.
  • ViewEncapsulation.None : utilisez le CSS global sans aucune encapsulation.
  • ViewEncapsulation.ShadowDom : utilisez Shadow DOM v1 pour encapsuler les styles.

Si elle n'est pas fournie, la valeur l'obtiendra de CompilerOptions. L'option par défaut du compilateur est ViewEncapsulation.Emulated.

Si la stratégie est définie sur ViewEncapsulation.Emulated et que le composant ne spécifie pas de styles ou de styleUrls, il passera automatiquement à ViewEncapsulation.None.

Avez-vous trouvé le type d'énumération ? Pourquoi n'y a-t-il pas de 1 ? Nous en reparlerons plus tard.

ViewEncapsulation.ShadowDom

Laissons de côté l'encapsulation de ShadowDom dans Angular, voyons d'abord ce qu'est ShadowDOM.

Shadow DOM

Shadow DOM permet à l'arborescence DOM cachée d'être attachée à l'arborescence DOM normale - elle commence par le nœud racine fantôme comme nœud racine. Sous ce nœud racine, il peut s'agir de n'importe quel élément et du DOM ordinaire. éléments.

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

Ici, il y a quelques termes spécifiques au Shadow DOM que nous devons comprendre :

  • Shadow host : un nœud DOM standard, Shadow DOM sera attaché à ce nœud.
  • Shadow Tree : L'arborescence DOM à l'intérieur de Shadow DOM.
  • Limite de l'ombre : là où le Shadow DOM se termine et où le DOM normal commence.
  • Shadow root : Le nœud racine de l'arbre Shadow.

Vous pouvez manipuler le Shadow DOM de la même manière qu'un DOM classique - par exemple en ajoutant des nœuds enfants, en définissant des propriétés et en ajoutant votre propre style au nœud (par exemple via l'attribut element.style) ou à l'ensemble. Ombre Ajoutez des styles au DOM (par exemple, en ajoutant des styles dans l'élément ). La différence est que les éléments à l'intérieur du Shadow DOM n'affecteront jamais les éléments à l'extérieur (sauf :focus-within), ce qui facilite l'encapsulation.

Prenons un exemple simple.

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>

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

L'exemple ci-dessus définit le style span global et définit également le style span dans shadowDOM. On peut voir qu'ils ne sont pas affectés les uns par les autres.

Encapsulation de ShadowDOM dans Angular

Après avoir compris ce qu'est ShadowDOM, jetons un œil à l'encapsulation de ShadowDOM dans Angular.

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 {
  ......
}

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

从运行的页面上看到,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 {
 ......
}

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

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 {
  ......
}

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

被废弃的Native

在Angular2中使用ViewEncapsulation.Native。

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

Comment Angular implémente-t-il lencapsulation des vues ? Parlons de trois modes de packaging

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

总结

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer