Angular 2+中如何从父组件为动态加载组件应用样式
解决Angular动态加载组件无法继承父组件样式的问题
这个问题我之前也碰到过,Angular默认的视图封装机制确实会让动态加载的组件和父组件的样式隔离开,导致你写在app-root里的app-stuff样式无法作用到动态创建的组件上。下面给你几个可行的解决方案:
方案一:用::ng-deep穿透样式
这是最常用的方法,通过::ng-deep让父组件的样式穿透到所有子组件(包括动态加载的)。为了避免全局样式污染,最好把它包裹在父组件的容器选择器内:
修改app.component.scss:
.componentList { display: flex; flex-direction: row; } .componentList ::ng-deep app-stuff { margin: 5px; }
这样样式只会作用在.componentList容器下的app-stuff组件,不管是静态写在模板里还是动态加载的都能生效。
方案二:动态设置宿主元素样式
如果你只需要给动态组件加少量样式,可以直接在创建组件时操作它的宿主元素:
修改AppComponent的loadComponent方法:
loadComponent() { const ref = this.replaceDiv.createComponent(StuffComponent); // 直接给宿主元素设置margin样式 ref.location.nativeElement.style.margin = '5px'; }
这种方式不需要修改样式文件,逻辑更直接,适合简单样式需求。
方案三:使用全局样式
把app-stuff的样式放到全局样式文件(比如项目根目录的styles.scss)中:
app-stuff { margin: 5px; }
全局样式会作用于所有的app-stuff组件,不管加载方式如何。但要注意,这种方式会影响整个应用里的app-stuff,如果有不需要这个样式的组件,就得额外覆盖样式。
方案四:修改组件的视图封装方式
可以把StuffComponent的视图封装改成None,这样它会继承父组件的样式:
修改StuffComponent:
import { Component, OnInit, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-stuff', template: '<p></p>', styleUrls: ['./stuff.component.scss'], encapsulation: ViewEncapsulation.None }) export class StuffComponent implements OnInit { constructor() { } ngOnInit() { } print() { console.log('### stuff ###'); } }
不过这个方法要谨慎使用,因为ViewEncapsulation.None会让该组件的样式变成全局样式,可能会和其他组件的样式冲突。
内容的提问来源于stack exchange,提问作者Fábio Tavares
相关产品推荐
相关产品推荐

