指导是一个很简单的话题,但是你很难搜索到介绍它的比较完整的文章,或者简单的告诉你ViewEncapsulation的用法,在实际项目中是很不实用的。不够。1、封装方式有:Native原始浏览器ShadowDOM行为。Emulated模拟模式,通过Angular来模拟类似于ShadowDOM的行为。无无封装行为。上述三种模式的唯一区别在于ShadowDOM。当然它的作用是让组件的样式只进出。也就是说,组件内部的样式不会影响外部组件。这里没有讨论有关ShadowDOM的更多详细信息。三者的表达式假设代码如下:不同模式生成的HTML&CSS样式不同,了解这些差异尤为重要。它们是:Native:#shadow-root(open)
测试
仿真:
testNone:test
Native&None在内容上是一样的,只是后者影响h1元素到其他外部组件。2、组件样式组件样式的封装方式取决于我们对封装的配置,比如上面的例子。当然,你可以在main.ts中为所有组件设置统一的行模式,例如:platformBrowserDynamic().bootstrapModule(AppModule,{defaultEncapsulation:ViewEncapsulation.None})虽然三种模式风格不同,但是对于一个组件来说,如果没有合理的使用方式,在实际项目中会让我们很头疼,尤其是当项目使用了第三方组件库(例如:ngx-bootstrap、ng-zorro-antd、material2等)的时候。很容易受到组件库的影响,或者需要在组件库和业务组件风格之间做一些微调的时候,了解一些细节是非常重要的。例如,一个用于渲染页眉名称:app-header组件,其中breadcrumbs会默认将最后一项加粗,但假设这不是我们想要的,而应该是不同的加粗文字likeotheritems:HomeDetail最终生成的HTML看起来像这样:跨度>/Detail/如果你不考虑在app里-添加到header组件的styles属性:.ant-breadcrumb-link{font-weight:normal;}如你所料,可能没有你想要的结果,或者结果可能存在隐患。前面说了三种模式唯一不同的就是ShadowDOM,所以说白了就是两种不同的结果。如果组件设置为None模式,会生效,但是只要app-header组件出现一次,即使不再使用app-header组件,以后所有面包屑的最后一项也不会加粗,这就是我说的隐患。相反,对于Shadowbehavior,它会创建一个额外的属性_ngcontent-c1,供nz-breadcrumb识别(无论是Native还是Emulated,本质都是一样的)设置样式仅限于app-header组件。在Angular中,:host用于表示组件本身,所以之前的CSS样式应该变成这样::host.ant-breadcrumb-link{font-weight:normal;}最终生成的样式会变成这样:[_nghost-c1].ant-breadcrumb-link[_ngcontent-c1]{font-weight:normal;}我认为我们不需要了解生成的标识符是怎样的。我们只需要知道:host就是组件本身。但是我们会发现,对于第三方组件nz-breadcrumb组件,.ant-breadcrumb-link只是组件内部的一个HTML元素的类,它有自己的一套组件封装规则。但是我们生成的CSS中包含了一个奇怪的字符[_ngcontent-c1],最终导致app-header组件样式无法改变第三方组件nz-breadcrumb组件的内容样式。这很有道理,我的地盘不可侵犯,Angular组件本身就是WebComponent标准的具体实现。难道我们没有办法去侵犯第三方组件吗?幸运的是,Angular提供了一个命令::ng-deep以更好地与未来的工具兼容,以强制样式并允许侵入子组件。:host::ng-deep.ant-breadcrumb-link{font-weight:normal;}生成的CSS将是这样的:[_nghost-c1].ant-breadcrumb-link{font-weight:normal;}最后这个不是加粗效果只在app-header组件内部有效。总结熟悉:host和::ng-deep的组合对于构建组件样式至关重要。Angular组件有自己的业务逻辑、样式和HTML模板,这些是构建WebComponent的核心技术。希望本文能帮助大家更好的理解组件样式。编码愉快!