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

时间:2016-03-01 21:39:48

标签: angular

所以我有一个名为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 个答案:

答案 0 :(得分:19)

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

<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" ...>

答案 1 :(得分:6)

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">

答案 2 :(得分:5)

<强>更新

所有新浏览器现在都支持

::slotted,并且可以与`ViewEncapsulation.ShadowDom

一起使用

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

<强>原始

/deep/::shadow>>>已弃用。 在所有浏览器都正确支持样式封装并且::ng-deep可以删除之前,ViewEncapsulation.Emulated是最佳选择。

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

因此,

/deep/::shadow>>> ::ng-deep可以在Angular2中正常使用。

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

答案 3 :(得分:1)

如果要让组件自己来定义实际的CSS,可以尝试以下操作之一:

为每个“逻辑”样式设置(例如headerSize)在组件上添加属性。

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

然后,您的组件可以使用以下几种样式来检查其值:

  1. 通过显示或隐藏子元素来修改HTML本身

    <h1 *ngIf="headerSize == 'large'">{{ title }}</h1>
    <h2 *ngIf="headerSize == 'small'">{{ title }}</h2>
    
  2. 在组件内部某个位置动态设置自定义类,并设置其样式:

    <div [ngClass]="'header-' + headerSize">
    
    .header-small { h1 { font-size: 20px; } }
    .header-large { h1 { font-size: 30px; } }
    
  3. 在类级别动态设置自定义类。与#2相同,不需要包装元素。但是,less than trivial实际上是启用和禁用这些类。

    @HostBinding('class.header-small') _header_small;
    @HostBinding('class.header-large') _header_large;
    

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

答案 4 :(得分:0)

另一个选择是使用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);
}

当然,这意味着您必须定义要设置样式的每个属性,但是如果只需要在子级上设置一些样式,则效果很好。