我有一个示例存储库https://github.com/collinstevens/angular-encapsulation它演示了我的问题。
共有三个组件:EmulatedComponent、NativeComponent 和 ShadowDomComponent,分别使用 ViewEncapsulation.Emulated、ViewEncapsulation.Native 和 ViewEncapsulation.ShadowDom。
来自 EmulatedComponent 的样式被复制到
<head>
中,如 https://angular.io/guide/component-styles 中所述,但也被复制到每个 #shadow-root 中,我想知道为什么,以及如果可能的话如何防止这种情况。
emulated.component.scss
div {
width: 50px;
height: 50px;
background-color: black;
display: inline-block;
}
native.component.scss
div {
width: 50px;
height: 50px;
background-color: red;
display: inline-block;
}
shadow-dom.component.scss
div {
width: 50px;
height: 50px;
background-color: yellow;
display: inline-block;
}
这是一个已知的bug,目前的解决方法是基本上不混合封装模式。
但是我假设您遇到的情况可能是您正在混合具有不同类型封装模式的第三方?如果是这样,您要么必须考虑您的 css 结构,要么只是重新考虑您正在混合的第三方库。
更新
考虑到注释使所有组件运行本机封装,通过使用 compilerOptions 告诉编译器这样做,以免与本机 Web 组件发生冲突。
通过添加 tsconfig.json 文件(ng 版本 6+ 中为 tsconfig.app.json)来实现此目的:
"angularCompilerOptions": {
"defaultEncapsulation": 1
}
三者的主要区别:
1-
ViewEncapsulation.Emulated
它预处理 CSS 代码以深入到组件以防止冲突,这是 Angular 的默认模式,因为浏览器中的 Shadow dom 支持有限......对于浏览器支持我可以使用
2-
ViewEncapsulation.Native
根据 Angular 文档 Read,它正在使用已弃用的 Shadow dom 版本。
它的工作原理几乎与 Shadow dom 封装相同
3-
ViewEncapsulation.ShadowDom
当您使用 ShadowDom
时,为什么会在每个 #shadow-root 中复制样式,因为这就是它的工作原理...当您激活 ShadowDom
时,它允许隐藏 DOM 树附加到常规树它就像常规 DOM 树中的树,因此它通过创建高级范围来复制应用于元素的样式,您实际上看到的是影子 dom,但理论上是常规 DOM...
欲了解更多有关 Shadow Dom 的信息,请阅读 MDN 文章
为了获得最佳实践,Angular 团队建议使用
ViewEncapsulation.Emulated
,这是默认设置,但在极少数情况下,您可以使用 None
或 ShadowDom
,但请谨慎使用。
今天依然如此。除了“不混合 ViewEncapsulation”之外的任何解决方法,这都不是 Angular 团队提供的真正好的解决方案。 :/