有人能解释一下视图封装.本机,****视图封装.无和视图封装.在angular2中模拟之间的区别吗?
我试着在谷歌上搜索,读了一些文章,但我无法理解其中的区别。
下面我有两个组件Home(home.ts),即父组件和MyComp(my-comp.ts)。我想在父组件中定义子组件中使用的样式。
我应该使用视图封装.本机还是视图封装.无
- 家.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 {
}
- 我的公司ts*
import {Component} from 'angular2/core';
@Component({
selector: 'my-comp', // <home></home>
template: `
<div class="parent-comp-width">my-comp</div>
`
})
export class MyComp {
}
6条答案
按热度按时间mrzz3bfm1#
Parent
的样式应用到Child
,则需要在Parent
组件中设置ViewEncapsulation.None
,以便它不会阻止样式渗入。Emulated
和Native
只是防止样式渗入组件和从组件渗出的两种不同方法。None
是唯一允许样式跨越组件边界的方法。将属性添加到组件标签和子元素,并操作添加到页面的CSS(将属性添加到选择器),以使样式不会彼此渗透,从而使样式的作用域限于添加它们的组件,即使在加载组件时样式都是在页面的头部收集添加的。
如果浏览器本身不支持shadow DOM,则需要web组件的polyfill来填充该行为。这类似于
ViewEncapsulation.Emulated
,但polyfill更昂贵,因为它们填充了大量的浏览器API,即使其中大部分从未使用过。AngularEmulated
仿真只是增加了它所使用的成本,因此对于Angular应用程序来说效率要高得多。7fhtutme2#
***本机:**使用浏览器的本机Shadow DOM。请在启用之前检查浏览器支持。
***ShadowDom:**使用浏览器的本机Shadow DOM v1以获得更好的跨浏览器支持,它是跨浏览器的共享标准。请检查Shadow DOM v0与v1之间的差异。
***Emulated:**模仿Shadow DOM的行为,以确定组件的CSS范围并将其附加到head。
***无:**既不支持Shadow DOM,也不支持自定义实现,如附加到头部的全局CSS
Angular 使用ViewEncapsulation。模拟为默认封装模式。
os8fio9y3#
让我们以
ComponentParent
包含ComponentChild
的场景为例,在这个例子中,我们讨论了ComponentParent
的不同封装场景。ViewEncapsulation有1个废弃值:
*
Native
-使用过时的Shadow DOM v0和3个有效值:
无
这是透明模式,与完全不涉及Angular 的场景最相似。
ComponentParent
和ComponentChild
都将具有黄色背景的H1标签。暗影穹顶
此模式在组件周围创建***一个本地阴影DOM***根(在我们的示例中:
ComponentParent
)内容。这将保护我们在组件内部声明的任何(CSS/SASS)样式泄漏到组件外部。但是,它将应用于像ComponentChild
这样的子组件。ComponentParent
和ComponentChild
都将具有黄色背景的H1标签(类似于None
模式),但ComponentParent
之外的任何H1标签将不受影响。模拟
简而言之,这将
ComponentParent
中声明的样式ONLY和ONLY应用于ComponentParent
内容,但EXCLUDING子组件(如ComponentChild
)。换句话说,仅应用于“pure”HTML元素,而不应用于Angular web(组件)元素。只有
ComponentParent
将具有黄色背景的H1标签。关于模拟机制的其他说明
Emulated
模式通常对我们来说是透明的,因为我们更喜欢把我们的全局样式(影响ComponentParent
和ComponentChild
),它将渗透到None
和Emulated
组件及其子组件和HTML元素中。然而,假设
ComponentChild
是第三方组件,并且您希望对其进行样式化。如果在ComponentParent
组件上应用Emulated
模式,则无法进行样式化。这是由于Emulated
实现所致:ComponentParent
组件内的每个HTML元素都将使用component-name属性(无值)进行修饰,例如:*一米二十六分一x:对于组件容器
*一米二十七分一x:对于组件的内容
同时,我们的组件
ComponentParent
中的每个CSS选择器都将使用相同的component-name属性进行“封装”(条件化总的来说,这意味着只有
ComponentParent
的元素会受到影响,我们修饰第三方组件H1的目标将失败,因为它没有(相同的,如果有的话)组件名称属性(_ngcontent-c3
)针对第三方组件的解决方案:
ShadowDom
(如果可用)None
wqnecbli4#
from pro-angular book:
视图封装值:
*模拟:当指定此值时,Angular通过编写内容和样式以添加属性来模拟阴影DOM。如果未指定封装值,则这是默认行为。
如果您使用浏览器的F12开发工具检查DOM,您将看到外部CSS文件的内容。
选择器已经过修改,可以将div元素与名为
_ngcontent-c0
的属性匹配,不过您可能会在浏览器中看到不同的名称,因为该属性的名称由Angular动态生成。要确保style元素中的CSS仅影响组件管理的HTML元素,请修改模板中的元素,使其具有相同的动态生成属性,如下所示:
***本机:**指定此值后,Angular将使用浏览器的阴影DOM功能。仅当浏览器实现阴影DOM或使用多边形填充时,此功能才有效。
***None:**当指定此值时,Angular只是将未修改的CSS样式添加到HTML文档的head部分,并让浏览器使用正常的CSS优先级规则来确定如何应用样式。
o7jaxewo5#
如果有人因为想通过父组件样式声明来设置子组件的样式而遇到这个问题,请参见this SO answer。
然而,正如对公认答案的最新评论所表明的那样,Angular文档说:
穿透阴影的后代组合符已被弃用,主要的浏览器和工具也将不再支持它。因此,我们计划在Angular中不再支持它(/deep/,〉〉〉和::ng-deep)。在此之前,应该首选::ng-deep以获得与这些工具更广泛的兼容性。
ahy6op9u6#
请参考以下示例以了解所有三个选项:
Click here以查看示例