AngularWie kapsele ich Ansichten? Der folgende Artikel vermittelt Ihnen ein tiefgreifendes Verständnis der drei Methoden der Angular Encapsulation. Ich hoffe, er wird Ihnen hilfreich sein!
Wenn wir bei der täglichen Arbeit eine Komponente definieren, müssen wir deren Kapselung Kapselung berücksichtigen, das heißt, erwarten Sie, dass die in dieser Komponente definierten Stile nur auf diese Komponente wirken, oder tun Sie das? Ich möchte auf die globale Situation reagieren. In Angular können die Stile einer Komponente im Hostelement der Komponente gekapselt werden, sodass sie den Rest der Anwendung nicht beeinträchtigen. Der Component-Decorator bietet die Option encapsulation, um zu steuern, wie die Ansichtskapselung pro Komponente angewendet wird. [Verwandte Tutorial-Empfehlungen: „Angular Tutorial“]
Es gibt drei Kapselungsmodi in Angular, nämlich ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated und 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 }
Wenn nicht angegeben, wird der Wert von CompilerOptions abgerufen. Die Standard-Compileroption ist ViewEncapsulation.Emulated.
Wenn die Richtlinie auf ViewEncapsulation.Emulated eingestellt ist und die Komponente keine Stile oder styleUrls angibt, wechselt sie automatisch zu ViewEncapsulation.None.
Haben Sie den Aufzählungstyp gefunden? Mehr dazu später.
-Elements). Der Unterschied besteht darin, dass Elemente innerhalb des Shadow DOM niemals Elemente außerhalb davon beeinflussen (außer :focus-within), was die Kapselung erleichtert.
Schauen wir uns ein einfaches Beispiel an.<!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 使用浏览器内置的 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 { ...... }
从运行的页面上看到,user-child组件内部被封装成了一个ShadowDOM,style也被封装在了里面,并不会对外部的样式造成影响。
Angular 会修改组件的 CSS 选择器,使它们只应用于组件的视图,不影响应用程序中的其他元素(模拟 Shadow DOM 行为)。
使用模拟视图封装时,Angular 会预处理所有组件的样式,以便它们仅应用于组件的视图。在正运行的 Angular 应用程序的 DOM 中,使用模拟视图封装模式的组件所在的元素附加了一些额外的属性:
<hero-details _nghost-pmm-5> <h3 _ngcontent-pmm-5>Mister Fantastic</h3> <hero-team _ngcontent-pmm-5 _nghost-pmm-6> <h4 _ngcontent-pmm-6>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 { ...... }
ViewEncapsulation.Emulated 设置的结果是没有 Shadow DOM,但是通过 Angular 提供的样式包装机制来封装组件,使得组件的样式不受外部影响。虽然样式仍然是应用到整个 document,但 Angular 为 p创建了一个 [_ngcontent-oow-c11] 选择器。可以看出,我们为组件定义的样式,被 Angular 修改了。简单来说,尽管是也是全局样式,但是由于自动选择器的原因,并不会影响其他组件的样式。如果手动在其他元素上也添加这个属性,则样式也会应用到这元素上。
Angular 不应用任何形式的视图封装,这意味着为组件指定的任何样式实际上都是全局应用的,并且可以影响应用程序中存在的任何 HTML 元素。这种模式本质上与将样式包含在 HTML 本身中是一样的。
parent:
<p #caption>parent works!{{count}}</p> <p #caption>第一个:{{count}}</p> <span class="red-font">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 { ...... }
在Angular2中使用ViewEncapsulation.Native。
@Component({ ..., encapsulation: ViewEncapsulation.Native }) export class UserComponent {
ViewEncapsulation.Native 设置的结果是使用原生的 Shadow DOM 特性。Angular 会把组件按照浏览器支持的 Shadow DOM 形式渲染。其实这种就是后来的ViewEncapsulation.ShadowDom。
我们介绍了Angular视图封装的三种方式,各自的特点,日常工作中要根据特定的场景去选择哪种封装方式。
更多编程相关知识,请访问:编程视频!!
Das obige ist der detaillierte Inhalt vonWie implementiert Angular die Ansichtskapselung? Lassen Sie uns über drei Verpackungsmodi sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!