【问题标题】:Shared styles across components in an Angular 2 app在 Angular 2 应用程序中跨组件共享样式
【发布时间】:2016-06-12 15:30:44
【问题描述】:

我的 Angular 2 应用程序中有一些 CSS 规则,这些规则在各种组件中都很常见。显然我不想将它们复制并粘贴到每个组件的样式中。我目前有 2 个想法:

  1. 将常用 CSS 规则放在静态 CSS 文件中,并使用我 index.html 的 head 部分中的链接将其包含在内。
  2. 将我常用的 CSS 规则放在一个或多个文件中,并将它们包含在每个组件的 @Component 装饰器中,例如 styleUrls: [ './myComponentStyle.css', '../common/common.css']

第一种方法对我来说看起来不那么棱角分明,但同时它肯定有效且易于实施。

第二个需要对每个组件进行一些工作,但允许更多地控制一个正在使用的样式。它还让我可以将常用样式组织成更小的样式表,并且只使用需要的样式表。

您喜欢这些解决方案中的任何一个,还是有第三种更好的解决方案? :)

【问题讨论】:

    标签: css angular typescript stylesheet


    【解决方案1】:

    对于未来的读者,我认为这个解决方案是最好的。

    假设您有 2 个组件(productscustomers),并且有共同的样式要共享。

    1.再创建一个组件

    //customer-products-styles.component.ts
    @Component({
      selector: "app-customer-products-styles",
      template: "",
      styleUrls: ["./customer-products-styles.component.scss"],
      encapsulation: ViewEncapsulation.None,
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class CustomerProductsStylesComponent {}
    
    //customer-products-styles.component.scss
    app-products,
    app-customers {
      p {
        color: coral;
      }
    }
    

    2.像这样使用它

    <!-- Customers Component (app-customers) -->
    <app-customer-products-styles></app-customer-products-styles>
    <p>
      customers works!
    </p>
    
    <!-- Products Component (app-products) -->
    <app-customer-products-styles></app-customer-products-styles>
    <p>
      products works!
    </p>
    

    好处

    • 它是延迟加载的,在下载模块块时加载,初始 main.js 减少
    • 添加组件选择器(app-customersapp-products) 作为样式的父级使其成为组件范围
    • 没有重复的样式,并且只在浏览器中加载一次,无论组件首先请求它

    补充几点

    • encapsulation设置为none,但将组件选择器添加为样式中的父级
    • 我还将默认changeDetection 更改为OnPush,没有必要,但为了安全

    Working Stackblitz

    【讨论】:

      【解决方案2】:

      1. 这个解决方案不错,但更适合任何常见的样式,应该适用于所有组件。例如,css 网格的样式。 为了使它更加棱角分明,您可以将应用组件的封装设置为无:

      `@Component({
           selector: 'my-app',
           template: `  `,
           styleUrls: ["shared.style.css"],
           encapsulation: ViewEncapsulation.None
      }) export class App {}`  
      

      Demo could be found here (plunker)

      注意:通过这种方式包含的样式(仅添加样式标记或不封装)将影响页面上的所有元素。有时它是我们真正想要的(同意使用任何 CSS 框架进行孔项目)。但如果只是想在几个组件之间共享样式 - 这可能不是最好的方式。

       Summary: 
       (+) easy to use
       (-) no encapsulation
      

      2.我喜欢这个解决方案,因为它非常容易理解并且具有可预测的行为。 但是有一个问题

      它会在您每次使用时为您的共享样式添加样式标签。 如果您有大样式文件或使用它的许多元素,这可能是一个问题。

      @Component({
         selector: 'first',
         template: `<h2>  <ng-content> </ng-content> </h2>`,
         styleUrls: ["shared.style.css"]
      })
      export class FirstComponent {}
      

      Demo could be found here (plunker)

       Summary:
       (+) easy to use
       (+) encapsulation
       (-) duplicates styles for every usage
      

      3.您还可以使用另一种选择。 只需再创建一个组件,它会为其子级提供共享样式。

        ` <styles-container>
          <first> first comp  </first>
        </styles-container>
        <styles-container>
          <second> second comp </second>
        </styles-container>`
      

      在这种情况下,您必须在样式中使用 /deep/ 以使样式可用于子组件:

      :host /deep/ h2 {
        color: red;
      }
      

      我还值得一提的是不要忘记使用 :host 使样式可用于子元素。如果您省略它,您将获得一种更全局的样式。

      Demo could be found here (plunker)

      Summary:
      (-) you have to create container and it in templates
      (+) encapsulation
      (+) no duplicated styles
      

      注意:封装样式是一个很酷的功能。但你也应该记住,没有办法限制你的深度风格。所以如果你应用了深度样式,它绝对适用于所有孩子,所以也要小心使用它。

      【讨论】:

      • 你好,很好的答案!关于#3,我读到:host/deep/ 将被弃用?从长远来看,使用#3 是否仍然可持续? angular.io/guide/component-styles#deprecated-deep--and-ng-deep
      • 这不是一个简单的问题。你可以阅读这个答案以获得更多的理解,深度发生了什么:stackoverflow.com/questions/47024236/…
      • 我喜欢第二种解决方案。
      • 对于 3. 和当前的 Angular,您需要将 host: /deep/ 替换为 styles-container,因为 host: 不适用于 ViewEncapsulation.None
      【解决方案3】:

      在 angular2 应用程序 (link) 中有 3 种使用样式的方法。 您已经提到了其中两个允许您重用样式的方法。

      我个人的看法是,对于任何大型应用程序,最好使用#2,这主要是因为 angular.js 提供了视图封装。

      #1 可用于应用程序所有部分通用的非常通用的样式。但是,如果您考虑到您的 SPA 中的根无论如何都是角度组件 - 没有真正需要使用除 #2 之外的另一种链接样式的方法。

      此外,通过以两种不同的方式使用 css,您必须记住这一点(并处理一些额外的代码),例如捆绑您的应用程序和使用 gulp-inline-ng2-template 之类的工具

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 2018-10-18
        • 1970-01-01
        • 1970-01-01
        • 2017-06-29
        • 1970-01-01
        相关资源
        最近更新 更多