Angular 2应用程序中各组件之间的共享样式

时间:2016-02-29 14:32:30

标签: angular typescript

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

  1. 将常见的CSS规则放在静态CSS文件中,并使用index.html' head部分中的链接将其包含在内。
  2. 将我的常用CSS规则放在一个或多个文件中,并将其包含在每个组件的@Component装饰器中,例如 styleUrls: [ './myComponentStyle.css', '../common/common.css']
  3. 对我来说,第一种方法看起来并不那么棱角分明,但同时它确实有效且易于实施。

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

    你喜欢这些解决方案还是有第三种更好的解决方案? :)

3 个答案:

答案 0 :(得分:30)

1。此解决方案很好,但它更适合任何常见样式,应该适用于所有组件。例如,css网格的样式。 为了使它更具棱角,您可以将app app组件的封装设置为none:

`@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。我喜欢这个解决方案,因为它非常容易理解且具有可预测的行为。 但是它有一个问题

每次使用时,它都会为您的共享样式添加样式标记。 如果您有大型样式文件或许多正在使用它的元素,则可能会出现问题。

duplicated styles

@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;
}

我还值得一提的是不要忘记使用:主持人为子元素提供的样式。如果省略它,你将获得另一种全球风格。

Demo could be found here (plunker)

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

注意:封装样式真的很酷。但你也应该记住,没有办法限制你的深刻风格。因此,如果您应用深度样式,它将绝对适用于所有孩子,所以也要小心使用它。

答案 1 :(得分:1)

在angular2 app(link)中有3种方式可以使用样式。 您已经提到了其中两个允许您重用样式的内容。

我个人认为,对于任何大型应用程序,它最好与#2一起使用,主要是由于angular提供的视图封装。

#1可用于应用程序所有部分通用的非常通用的样式。但是如果你考虑到你的SPA中的根仍然是角度分量 - 没有必要采用另一种链接样式而不是#2的方法。

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

答案 2 :(得分:0)

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

假设您有 2 个组件(产品客户),并且有要共享的通用样式。

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