有人可以解释 ViewEncapsulation.Native, ViewEncapsulation.None 与 ViewEncapsulation.Emulated 之间的区别> angular2
我试图谷歌并阅读一些文章,但我无法理解其中的差异。
下面我有两个组件Home(home.ts),即父组件和MyComp(my-comp.ts)。我想在父组件中定义正在子组件中使用的样式。
我应该使用 ViewEncapsulation.Native 还是 ViewEncapsulation.None
home.ts
import {Component, ViewEncapsulation} from 'angular2/core';
import {MyComp} from './my-comp';
@Component({
selector: 'home', // <home></home>
providers: [
],
directives: [
MyComp
],
styles: [`
.parent-comp-width {
height: 300px;
width: 300px;
border: 1px solid black;
}
`],
template:`
<my-comp></my-comp>
<div class="parent-comp-width"></div>
`,
encapsulation: ViewEncapsulation.Native
})
export class Home {
}
MY-comp.ts
import {Component} from 'angular2/core';
@Component({
selector: 'my-comp', // <home></home>
template: `
<div class="parent-comp-width">my-comp</div>
`
})
export class MyComp {
}
答案 0 :(得分:20)
<强>更新强>
如果您希望将Parent
添加到Child
的样式应用于ViewEncapsulation.None
,则需要在Child
组件中设置Emulated
,以防止样式出血。
Native
和None
只是阻止样式进出组件的两种不同方法。 ViewEncapsulation.Emulated
是唯一允许样式跨越组件边界的方法。
<强>原始强>
ViewEncapsulation.None很简单,没有封装
ViewEncapsulation.Emulated(目前是Angular2中的默认值)
将属性添加到组件标签和子元素,并操纵添加到页面的CSS(将属性添加到选择器),以便样式不会相互渗透 - 将样式作为范围保存到添加它们的组件,即使样式在加载组件时,都会在页面的头部收集所有内容。
ViewEncapsulation.Native使用shadow DOM创建自定义元素,其中浏览器本机实现确保样式范围。
如果浏览器本身不支持shadow DOM,则需要Web组件polyfill来填充行为。这类似于Emulated
,但是polyfill更昂贵,因为它们填充了大量的浏览器API,即使它们中的大多数从未使用过。 Angulars <div id="Insert_here">Name
<div id="Image">Name //Or whatever you call it.
仿真只会增加它使用的成本,因此对Angular应用程序来说效率更高。
答案 1 :(得分:2)
Angular使用ViewEncapsulation。模拟为默认封装模式。
答案 2 :(得分:0)
如果有人因为想要通过父组件样式声明来设置子组件的样式而遇到这个问题,请参阅this SO answer。
但是,正如对接受的答案的最新评论所示,Angular docs说:
阴影穿透后代组合子已被弃用且支持 从主要浏览器和工具中删除。因此我们打算放弃 支持Angular(对于所有3个/ deep /,&gt;&gt;&gt;和:: ng-deep)。直到 那么:: ng-deep应该是首选,以实现更广泛的兼容性 工具。
答案 3 :(得分:0)
ViewEncapsulation值:
模拟:指定此值后,Angular会通过编写内容和样式以添加属性来模拟Shadow DOM。如果未指定封装值,这是默认行为。
如果使用浏览器的F12开发人员工具检查DOM,您将看到外部CSS文件的内容。
... <style> div[_ngcontent-c0] { background-color: lightcoral; } </style> ...
修改了选择器,使其与div元素匹配
名为_ngcontent-c0
的属性,尽管您可能会在
属性名称是由Angular动态生成的。
为了确保style元素中的CSS仅影响由组件管理的HTML元素,请修改模板中的元素,使其具有相同的动态生成的属性,如下所示:
...
<div _ngcontent-c0="" class="form-group">
<label _ngcontent-c0="">Name</label>
<input _ngcontent-c0="" class="form-control ng-untouched ng-pristineng-invalid"
ng-reflect-name="name" name="name">
</div>
...
“ Native”和“ None”值应谨慎使用。浏览器对影子DOM功能的支持非常有限,以至于仅当您使用提供与其他浏览器兼容的polyfill库时,才可以使用Native选项。
“无”选项将组件定义的所有样式添加到HTML文档的开头部分,并使浏览器确定如何应用它们。这样做的好处是可以在所有浏览器中使用,但是结果是不可预测的,并且不同组件定义的样式之间没有隔离。
答案 4 :(得分:0)
请参考以下示例以了解所有三个选项:
encapsulation: ViewEncapsulation.Emulated
encapsulation: ViewEncapsulation.Native
encapsulation: ViewEncapsulation.None
Click here看例子
答案 5 :(得分:0)
让我们以ComponentParent
包含ComponentChild
的情况为例。对于此示例,我们将讨论ComponentParent
的不同封装方案。
import { ViewEncapsulation } from '@angular/core';
@Component({
selector: 'component-child',
// templateUrl: './child.component.html',
template: '<h1>Hello, child</h1>',
// styleUrls: ['./child.component.scss'],
style: '/* ... */'
})
export class ComponentParent {
// ...
}
@Component({
selector: 'component-parent',
template: '<h1>Hello, parent</h1><component-child/>',
style: 'h1{background-color:yellow}',
encapsulation: ViewEncapsulation.Emulated // this is the default encapsulation for the angular component
})
export class ComponentParent {
// ...
}
ViewEncapsulation具有1个废弃的值:
Native
-使用不推荐使用的Shadow DOM v0 和3个有效值:
这是透明模式,最类似于根本不涉及角度的情况。
ComponentParent
和ComponentChild
都将带有黄色背景的H1标签。
此模式在组件(在我们的示例中为ComponentParent
)内容周围创建 本地阴影DOM 根。这将保护我们在组件内部声明的任何(CSS / SASS)样式,以泄漏到组件外部。但是,它将应用于诸如ComponentChild
之类的子组件。
ComponentParent
和ComponentChild
都将带有带有黄色背景的H1标签(类似于None
模式),但是ComponentParent
之外的任何H1标签都不会受到影响。
简而言之,这仅将ComponentParent
中声明的样式应用于ComponentParent
内容,但排除子组件,例如ComponentChild
。换句话说,仅在“ 纯” HTML元素上,而不在有角网(组件)元素上。
只有
ComponentParent
的H1标签带有黄色背景。
Emulated
模式通常对我们来说是透明的,因为我们倾向于放置将同时渗透ComponentParent
和{的全局样式(影响ComponentChild
和None
)。 {1}}组件及其子组件和HTML元素。
但是,假设Emulated
是第3方组件,并且您想为其设置样式。如果在ComponentChild
组件上应用Emulated
模式,则将无法执行此操作。这是由于ComponentParent
实现:
Emulated
组件内的每个HTML元素将使用component-name属性(无值)修饰,例如:
ComponentParent
:用于组件容器_nghost-c3
:获取组件的内容我们的组件_ngcontent-c3
中的并行每个(S)CSS选择器将被“封装”(带有条件),具有相同的组件名称属性
ComponentParent
总体而言,这意味着仅.H1[_ngcontent-c3] {
background-color:yellow;
}
的元素会受到影响,而我们装饰第三方组件的H1的目标将失败,因为它没有(相同,如果有的话)组件-name属性(ComponentParent
)
第三方组件的解决方案:
_ngcontent-c3
(如果可用)ShadowDom