angularJS2组件样式

把样式加载进组件中

我们有几种方式来把样式加入组件:

内联在模板的 HTML 中

设置styles或styleUrls元数据

通过 CSS 文件导入

上述作用域规则对所有这些加载模式都适用。
元数据中的样式

我们可以给@Component装饰器添加一个styles数组型属性。 这个数组中的每一个字符串(通常也只有一个)定义一份 CSS。

  @Component({
      selector: 'hero-app',
      template: `
        <h1>Tour of Heroes</h1>
        <hero-app-main [hero]=hero></hero-app-main>`,
      styles: ['h1 { font-weight: normal; }']
    })
    export class HeroAppComponent {
    /* . . . */
    }

模板内联样式
我们也可以把它们放到

  @Component({
      selector: 'hero-controls',
      template: `
        <style>
          button {
            background-color: white;
            border: 1px solid #777;
          }
        </style>
        <h3>Controls</h3>
        <button (click)="activate()">Activate</button>
      `
    })

元数据中的样式表 URL

我们还可以通过给组件的@Component装饰器中添加一个styleUrls属性来从外部 CSS 文件中加载样式:

    @Component({
      selector: 'hero-details',
      template: `
        <h2>{{hero.name}}</h2>
        <hero-team [hero]=hero></hero-team>
        <ng-content></ng-content>
      `,
      styleUrls: ['app/hero-details.component.css']
    })
    export class HeroDetailsComponent {
    /* . . . */
    }

URL是相对于应用程序根目录的,它通常是应用的宿主页面index.html所在的地方。 这个样式文件的 URL 不是相对于组件文件的。这就是为什么范例中的 URL 用app/开头。 参见附录 2 来了解如何指定相对于组件文件的 URL。

像 Webpack 这类模块打包器的用户可能会使用styles属性来在构建时从外部文件中加载样式。它们可能这样写:

styles: [require(‘my.component.css’)]

注意,这时候我们是在设置styles属性,而不是styleUrls属性! 是模块打包器在加载 CSS 字符串,而不是 Angular。 Angular 看到的只是打包器加载它们之后的 CSS 字符串。 对 Angular 来说,这跟我们手写了styles数组没有任何区别。 要了解这种 CSS 加载方式的更多信息,请参阅相应模块打包器的文档。
模板中的 link 标签

我们也可以在组件的 HTML 模板中嵌入标签。

像styleUrls标签一样,这个 link 标签的href指向的 URL 也是相对于应用的根目录的,而不是组件文件。

  @Component({
      selector: 'hero-team',
      template: `
        <link rel="stylesheet" href="app/hero-team.component.css">
        <h3>Team</h3>
        <ul>
          <li *ngFor="let member of hero.team">
            {{member}}
          </li>
        </ul>`
    })

CSS @imports

我们还可以利用标准的 CSS @import规则来把其它 CSS 文件导入到我们的 CSS 文件中。

在这种情况下,URL 是相对于我们执行导入操作的 CSS 文件的。

app/hero-details.component.css (excerpt)
@import 'hero-details-box.css';

控制视图的封装模式:原生 (Native)、仿真 (Emulated) 和无 (None)

像上面讨论过的一样,组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。

通过在组件的元数据上设置视图封装模式,我们可以分别控制每个组件的封装模式。 可选的封装模式一共有三种:

Native模式使用浏览器原生的 Shadow DOM 实现来为组件的宿主元素附加一个 Shadow DOM。组件的样式被包裹在这个 Shadow DOM 中。(译注:不进不出,没有样式能进来,组件样式出不去。)

Emulated模式(默认值)通过预处理(并改名)CSS 代码来模拟 Shadow DOM 的行为,以达到把 CSS 样式局限在组件视图中的目的。 更多信息,见附录 1 。(译注:只进不出,全局样式能进来,组件样式出不去)

None意味着 Angular 不使用视图封装。 Angular 会把 CSS 添加到全局样式中。而不会应用上前面讨论过的那些作用域规则、隔离和保护等。 从本质上来说,这跟把组件的样式直接放进 HTML 是一样的。(译注:能进能出。)

通过组件元数据中的encapsulation属性来设置组件封装模式:

// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native

原生(Native)模式只适用于有原生 Shadow DOM 支持的浏览器。 因此仍然受到很多限制,这就是为什么我们会把仿真 (Emulated) 模式作为默认选项,并建议将其用于大多数情况。
附录 1:查看仿真 (Emulated) 模式下生成的 CSS

当使用默认的仿真模式时,Angular 会对组件的所有样式进行预处理,让它们模仿出标准的 Shadow CSS 作用域规则。

当我们查看启用了仿真模式的 Angular 应用时,我们看到每个 DOM 元素都被加上了一些额外的

<hero-details _nghost-pmm-5>
  <h2 _ngcontent-pmm-5>Mister Fantastic</h2>
  <hero-team _ngcontent-pmm-5 _nghost-pmm-6>
    <h3 _ngcontent-pmm-6>Team</h3>
  </hero-team>
</hero-detail>

到了两种被生成的属性:

一个元素在原生封装方式下可能是 Shadow DOM 的宿主,在这里被自动添加上一个_nghost属性。 这是组件宿主元素的典型情况。

组件视图中的每一个元素,都有一个_ngcontent属性,它会标记出该元素是哪个宿主的模拟 Shadow DOM。

这些属性的具体值并不重要。它们是自动生成的,并且我们永远不会在程序代码中直接引用到它们。 但它们会作为生成的组件样式的目标,就像我们在 DOM 的区所看到的:

[_nghost-pmm-5] {
  display: block;
  border: 1px solid black;
}

h3[_ngcontent-pmm-6] {
  background-color: white;
  border: 1px solid #777;
}

这些就是我们写的那些样式被处理后的结果,于是每个选择器都被增加了_nghost或_ngcontent属性选择器。 在这些附加选择器的帮助下,我们实现了本指南中所描述的这些作用域规则。

小伙伴们会很愉快的使用仿真模式 —— 直到有一天 Shadow DOM 获得全面支持。
附录 2:使用相对 URL 加载样式

把组件的代码 (ts/js)、HTML 和 CSS 分别放到同一个目录下的三个不同文件,是一个常用的实践:

quest-summary.component.ts
quest-summary.component.html
quest-summary.component.css

我们会通过设置元数据的templateUrl和styleUrls属性把模板和 CSS 文件包含进来。 既然这些文件都与组件(代码)文件放在一起,那么通过名字,而不是到应用程序根目录的全路径来指定它,就会是一个漂亮的方式。

通过把组件元数据的moduleId属性设置为module.id,我们可以更改 Angular 计算完整 URL 的方式
app/quest-summary.component.ts

    @Component({
      moduleId: module.id,
      selector: 'quest-summary',
      templateUrl: 'quest-summary.component.html',
      styleUrls:  ['quest-summary.component.css']
    })
    export class QuestSummaryComponent { }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值