Angular뷰를 어떻게 캡슐화하나요? 다음 기사는 Angular Encapsulation의 세 가지 방법에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다.
일상 작업에서 Component를 정의할 때 encapsulation 캡슐화를 고려해야 합니다. 즉, 이 구성 요소에 정의된 스타일이 이 구성 요소에서만 작동할 것으로 예상합니까, 아니면 글로벌 상황에 맞춰 행동하고 싶습니다. Angular에서는 구성 요소의 스타일이 구성 요소의 호스트 요소 내에 캡슐화되어 애플리케이션의 나머지 부분에 영향을 주지 않습니다. Component 데코레이터는 뷰 캡슐화가 구성 요소별로 적용되는 방식을 제어하는 encapsulation 옵션을 제공합니다. [관련 튜토리얼 권장 사항: "angular Tutorial"]
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 }
제공되지 않은 경우 값은 CompilerOptions에서 가져옵니다. 기본 컴파일러 옵션은 ViewEncapsulation.Emulated입니다.
정책이 ViewEncapsulation.Emulated로 설정되어 있고 구성 요소가 스타일이나 styleUrls를 지정하지 않으면 자동으로 ViewEncapsulation.None으로 전환됩니다.
열거형을 찾으셨나요? 왜 1이 없나요? 이에 대해서는 나중에 자세히 설명합니다.
Angular의 ShadowDom 캡슐화는 제쳐두고 먼저 ShadowDOM이 무엇인지 살펴보겠습니다.
Shadow DOM을 사용하면 숨겨진 DOM 트리를 일반 DOM 트리에 연결할 수 있습니다. 이 루트 노드 아래에는 섀도우 루트 노드로 시작하고 일반 DOM이 될 수 있습니다. 강요.
여기서 우리가 이해해야 할 몇 가지 Shadow DOM 관련 용어가 있습니다.
일반 DOM과 동일한 방식으로 Shadow DOM을 조작할 수 있습니다. 예를 들어 하위 노드 추가, 속성 설정, 노드에 자신만의 스타일 추가(예: element.style 속성을 통해) 또는 전체 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('#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>
위 예시에서는 전역 스팬 스타일을 정의하고, 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 { ...... }
从运行的页面上看到,user-child组件内部被封装成了一个ShadowDOM,style也被封装在了里面,并不会对外部的样式造成影响。
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 { ...... }
ViewEncapsulation.Emulated 设置的结果是没有 Shadow DOM,但是通过 Angular 提供的样式包装机制来封装组件,使得组件的样式不受外部影响。虽然样式仍然是应用到整个 document,但 Angular 为 p创建了一个 [_ngcontent-oow-c11] 选择器。可以看出,我们为组件定义的样式,被 Angular 修改了。简单来说,尽管是也是全局样式,但是由于自动选择器的原因,并不会影响其他组件的样式。如果手动在其他元素上也添加这个属性,则样式也会应用到这元素上。
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 { ...... }
在Angular2中使用ViewEncapsulation.Native。
@Component({ ..., encapsulation: ViewEncapsulation.Native }) export class UserComponent {
ViewEncapsulation.Native 设置的结果是使用原生的 Shadow DOM 特性。Angular 会把组件按照浏览器支持的 Shadow DOM 形式渲染。其实这种就是后来的ViewEncapsulation.ShadowDom。
我们介绍了Angular视图封装的三种方式,各自的特点,日常工作中要根据特定的场景去选择哪种封装方式。
更多编程相关知识,请访问:编程视频!!
위 내용은 Angular는 뷰 캡슐화를 어떻게 구현합니까? 세 가지 포장 모드에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!