首页 文章

将样式传递给组件的最佳方法

提问于
浏览
22

所以我有一个名为 InputEdit 的组件(基本上是一个 Label ,点击它时可以编辑......很简单),这个组件有自己的阴影DOM CSS样式 . 但是当然每个托管组件都想为输入组件设置自己的字体大小和颜色......

那么最好的方法是什么?你能直接传入一个样式类并将整个CSS应用到组件中吗?或者最好手动传递每个值,如下所示:

<InputEdit [color]="'red'"/>

这似乎有很多工作,但是由于我们使用阴影或模拟DOM,我们不能只在外部控制CSS .

我也知道你可以通过以下方式拼接打开阴影并定位直接元素:

/* styles.css */
UserInfo /deep/ InputEdit label {
    color: red;
    font-size: 1.1em;
}

这将基本上允许您进入名为UserInfo / deep(任何级别)/自定义组件的自定义组件InputEdit和目标标签,颜色为红色...

但同样,我想知道什么是专门针对ng2的最佳方法,比如将类配置传递给指令呢?

5 回答

  • 5

    我只想在InputEdit上使用 styles input属性,并传入一个具有所需样式的对象:

    <InputEdit [styles]="stylesObj">                 // in host component's template
    
    stylesObj = {font-size: '1.1em', color: 'red'};  // in host component class
    
    <input [ngStyle]="stylesObj" ...>                // in InputEdit component's template
    

    如果要设置多个DOM元素,请传入更复杂的对象:

    <InputEdit [styles]="stylesObj">
    
    stylesObj = {
      input: {font-size: '1.1em', color: 'red'}
      label: { ... } 
    };
    
    <label [ngStyle]="styles.label" ...>
    <input [ngStyle]="styles.input" ...>
    
  • 0

    Mark Rajcok's答案适用于一组样式,但如果您只是允许更改字体大小和颜色,您可能希望使用更像您开始时更直接的方法(在此示例中,仅强制执行)像素而不是更灵活的字符串用于演示目的):

    适用于个性风格:

    零件:
    <InputEdit [color]="'red'" [fontSize]="16">

    component.ts:
    Input() color: string = 'black';
    Input() fontSize: number = 18;

    component.template:
    <input type="text" [style.color]="color" [style.fontSize.px]="fontSize">


    如果允许一组风格:

    零件:
    <InputEdit [styles]="{backgroundColor: 'blue', 'font-size': '16px'}"> 注意:如果有多个单词,请确保CSS属性是camelCased或字符串 .

    component.ts:
    @Input() styles: any = {};

    component.template:
    <input type="text" [ngStyle]="styles">

  • 1

    update

    所有新浏览器现在都支持 ::slotted ,可以与`ViewEncapsulation.ShadowDom一起使用

    https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

    original

    不推荐使用 /deep/::shadow>>> . ::ng-deep 是最好的选择,直到所有浏览器都正确支持样式封装,并且可以删除 ViewEncapsulation.Emulated .

    弃用仅适用于Chrome中的本机实现(其他浏览器从未实现过),但Angular在 ViewEncapsulation.Emulated 中有自己的这些CSS组合器仿真(默认)

    / deep /,:: shadow和>>> ::ng-deep 因此可以在Angular2中使用得很好 .

    对于简单的类或样式属性设置,请使用 ngStyle Angular 2.0 and ng-style

  • 18

    如果要将其留给组件来定义实际的css,可以尝试以下方法之一:

    在组件上为每个'logical'样式设置添加属性,例如 headerSize .

    @Input('headerSize') headerSize: ('small' | 'large');
    

    然后,您的组件可以通过以下几种方式之一检查其值:

    • 通过显示或隐藏子元素来修改HTML本身
    <h1 *ngIf="headerSize == 'large'">{{ title }}</h1>
    <h2 *ngIf="headerSize == 'small'">{{ title }}</h2>
    
    • 在组件内部动态设置自定义类,并设置样式:
    <div [ngClass]="'header-' + headerSize">
    
    .header-small { h1 { font-size: 20px; } }
    .header-large { h1 { font-size: 30px; } }
    
    • 在类级别动态设置自定义类 . 这与#2相同,并且实际上不启用和禁用这些类 .
    @HostBinding('class.header-small') _header_small;
    @HostBinding('class.header-large') _header_large;
    

    另请注意,如果您使用 ng-content ,则应用的样式是包含组件中定义的样式,而不是实际执行内容替换的组件 .

  • 5

    另一种选择是使用CSS变量 . 在这种情况下,要设置子组件标签的颜色和字体大小的样式,可以在父组件的CSS上设置两个变量,并在子组件的CSS中使用它们 .

    userInfo.component.css

    InputEdit {
      --label-color: red;
      --label-font-size: 1.1em;
    }
    

    inputEdit.component.css

    label {
      color: var(--label-color, #000);
      font-size: var(--label-font-size, 1em);
    }
    

    当然,这意味着您必须定义要设置样式的每个属性,但如果您只需要在子项上设置几个样式,它就可以正常工作 .

相关问题