【问题标题】:Best way to pass styling to a component将样式传递给组件的最佳方式
【发布时间】:2016-06-14 12:43:00
【问题描述】:

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

那么最好的方法是什么?你可以只传入一个样式类并将整个 CSS 应用到组件吗?还是像这样手动传递每个值会更好:

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

这看起来工作量很大,但由于我们使用的是阴影或模拟 DOM,我们不能只从外部控制 CSS。

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

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

这基本上可以让您进入一个名为 UserInfo / deep (any level) / custom component InputEdit 的自定义组件和红色的目标标签...

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

【问题讨论】:

    标签: angular


    【解决方案1】:

    我会在 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" ...>
    

    【讨论】:

    • 记得把 CSS 属性放在一个字符串中,如果它包含多个单词,则使用驼峰命名法。
    • 这种方法不允许为伪选择器传递样式,例如:hover
    【解决方案2】:

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

    对于单个样式属性

    组件:
    &lt;InputEdit [color]="'red'" [fontSize]="16"&gt;

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

    component.template:
    &lt;input type="text" [style.color]="color" [style.fontSize.px]="fontSize"&gt;


    如果允许一组样式

    组件:
    &lt;InputEdit [styles]="{backgroundColor: 'blue', 'font-size': '16px'}"&gt; 注意: 如果有多个单词,请确保 CSS 属性是驼峰式

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

    component.template:
    &lt;input type="text" [ngStyle]="styles"&gt;

    【讨论】:

      【解决方案3】:

      更新

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

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

      原创

      /deep/::shadow&gt;&gt;&gt; 已弃用。 ::ng-deep 是最好的选择,直到所有浏览器都正确支持样式封装并且可以删除 ViewEncapsulation.Emulated

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

      /deep/::shadow&gt;&gt;&gt;::ng-deep 因此可以在 Angular2 中正常使用。

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

      【讨论】:

      【解决方案4】:

      如果您想由组件来定义实际的 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,则应用的样式是包含组件中定义的样式,而不是实际执行内容替换的组件。

      【讨论】:

        【解决方案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);
        }
        

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

        【讨论】:

        • 由于 Angular 已经停止支持 IE11,这种方法可能会得到更广泛的采用——事实上,Material 甚至可能在某个时候开始采用这种方法。
        猜你喜欢
        • 2010-12-08
        • 2011-11-01
        • 1970-01-01
        • 2014-02-12
        • 2016-12-03
        • 1970-01-01
        • 1970-01-01
        • 2019-04-30
        • 2019-07-25
        相关资源
        最近更新 更多