在Angular2中为组件加载多个样式表

Posted

技术标签:

【中文标题】在Angular2中为组件加载多个样式表【英文标题】:Loading multiple stylesheet for a component in Angular2 【发布时间】:2017-04-07 09:06:33 【问题描述】:

我正在构建一个 angular2 应用程序。当我尝试为同一个组件加载多个样式表时,我遇到了多个问题。这是我正在做的代码:

import  Component  from '@angular/core';

@Component(
selector: 'my-tag',
templateUrl: 'my-tag.component.html',
styleUrls: [
    './style1.css',
    './style2.css'
    ]
)
export class MyTagComponent

现在这是我的问题:

当我尝试从其他目录中包含 css 文件时:

styleUrls: [
    './style1.css',
    '../public/style2.css'
]

我得到了错误

Uncaught Error: Expected 'styles' to be an array of strings.

在浏览器控制台中。

然后我将第二个样式表style2.css 包含在组件的目录中,并编写了第一个sn-p。现在正在加载样式,但正在全局加载。第二个样式表的类名与引导程序冲突,而不是引导程序的样式,第二个样式表的样式被全局应用,即其他组件的模板正在从第二个样式表设置样式。

styleUrls中列出的url不应该只应用在组件上,而不会对其他组件造成伤害吗?

谁能告诉我如何在不全局应用的情况下为特定组件加载多个 css 文件。

我也尝试了以下解决方法,但该样式已应用于我制作的所有组件。

styles: [
      require('./style1.css').toString(),
      require('../public/style2.css').toString()
 ]

附:我正在使用 webpack 作为我项目的模块打包器。

webpack.config(摘录)

 
    test: /\.css$/,
    exclude: helpers.root('src', 'app'),
    loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
  ,
  
    test: /\.css$/,
    include: helpers.root('src', 'app'),
    loader: 'raw'
  

【问题讨论】:

【参考方案1】:

我见过这种方法:

@Component(
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
)
export class AppComponent 

其中 app.component.css 有多个导入,因此:

@import url('/assets/plugins/bootstrap-datepicker/css/bootstrap-datepicker.css');
@import url('/assets/plugins/bootstrap-datepicker/css/bootstrap-datepicker3.css');
@import url('/assets/plugins/ionRangeSlider/css/ion.rangeSlider.css');
@import url('/assets/plugins/ionRangeSlider/css/ion.rangeSlider.skinNice.css');

我希望这会有所帮助。

【讨论】:

在当前版本的 Angular 4 中,你不能只在全局 styles.css 文件中执行这些导入语句吗? @davaus 这不是有点违背在styleUrls 中将值作为数组传递的目的。元名称本身就暗示了多个样式表。 你好 Kanra 先生。我同意;但是数组不起作用(我试过了),这个方法确实......【参考方案2】:

相信问题出在您传递给 ExtractPlugin.extract(loader: options|object) 的“样式”参数上。我认为它指的是这个加载器:https://github.com/webpack/style-loader,它将样式标签添加到 DOM,因此将全局应用您的样式。

前几天我遇到了这个问题,只是为了这篇文章而查找了上面的理由,应该回过头来正确修复它,但我只是通过简单地使用 css-loader 来解决它这个:

  
    test: /\.css$/,
    loader: "css-loader"
  

以及将封装设置为 ViewEncapsulation.Native,并且如您之前提到的,在加载的 CSS 上调用 .toString()。不过,我想 ExtractTextPlugin 仍然可以在移除“样式”加载器的情况下使用。

【讨论】:

【参考方案3】:

我们通过分别设置 templateUrl 和 styleUrls 元数据属性来包含模板和 CSS 文件。因为这些文件与组件位于同一位置,所以最好按名称引用它们,而不必指定返回应用程序根目录的路径。

我们可以改变 Angular 计算完整 URL 的方式,将组件元数据的 moduleId 属性设置为 module.id

@Component(
  selector: 'my-tag',
  moduleId: module.id,
  templateUrl: 'my-tag.component.html',
  styleUrls:  ['style1.css', 'style2.css']
)
export class MyTagComponent  

更新#1

对于 webpack:

尝试在 webpack 配置中为 css 使用“to-string-loader”。

 test: /\.css$/, loaders: ['to-string-loader', 'css-loader'] 

希望对你有用。

【讨论】:

我使用 webpack 作为模块打包器。当我们将 systemjs 作为模块捆绑器时,您的解决方案就可以工作。 我为 webpack 添加了更新,请查看上面的更新#1。谢谢 我尝试了您的配置,但没有成功。我已经在上面发布了我的 webpack.config。如果我错了,请纠正我,但to-string-loadertoString() 的作用相同,不是吗?正如我上面提到的,当我添加 toString() 时,样式表已加载,但它正在全局加载,并且所有其他组件都受到它的影响。 尝试在您的组件元标记中添加encapsulation: ViewEncapsulation.None,因为您必须导入它=> import ViewEncapsulation from '@angular/core'; 签出。 其实我也试过了,但是也没用。

以上是关于在Angular2中为组件加载多个样式表的主要内容,如果未能解决你的问题,请参考以下文章

web优化-样式表脚本

如何在全局样式表中设置角度4组件选择器的样式?

React Native 外部样式表不更新组件

Laravel 5 样式表和脚本未为非基本路由加载

如何在 Angular 2 中将 SASS 用于组件样式?

如何将全局样式表导入组件 vue?