Angular之自定義組件添加默認樣式

Angular的核心思想之一就是:組件化。組件化可以使我們的代碼更好的複用。

在使用官方提供的Angular庫Angular Material時,細心的同學就會發現,Material的每一個組件都有它自己樣式,如:

  • 按鈕mat-button
  • 工具條mat-toolbar
  • 表格mat-table
  • etc.

每個組件添加自己獨有的樣式,增加css作用域的控制,實現了樣式的隔離。

那麼,如果給一個自定義組件添加默認樣式呢?接下來我們介紹三種方法來實現我們的目標。

方法一:host

在組件的@Component裝飾器中提供了host屬性,該屬性可以爲我們提供很多功能的支持,其中一項就是給組件添加樣式。

以Material中的Table爲例:

@Component({
 moduleId: module.id,
 selector: 'mat-table, table[mat-table]',
 exportAs: 'matTable',
 template: CDK_TABLE_TEMPLATE,
 styleUrls: ['table.css'],
 host: {
   'class': 'mat-table',
 },
 providers: [{provide: CdkTable, useExisting: MatTable}],
 encapsulation: ViewEncapsulation.None,
 // See note on CdkTable for explanation on why this uses the default change detection strategy.
 // tslint:disable-next-line:validate-decorators
 changeDetection: ChangeDetectionStrategy.Default,
})
export class MatTable<T> extends CdkTable<T> {
 /** Overrides the sticky CSS class set by the `CdkTable`. */
 protected stickyCssClass = 'mat-table-sticky';
}


















在MatTable的源碼中,我們可以看到爲host屬性設置了'class': 'mat-table',在我們使用MatTable組件時,就會添加上默認的樣式: mat-table.

注意

雖然Angular中提供了host屬性,並且官方的Material庫也是使用該屬性實現了很多功能,但是,在Angular編碼規範中卻不推薦使用該方法。詳見:HostListener 和 HostBinding 裝飾器 vs. 組件元數據 host


方法二:HostBinding

如方法一中注意事項中提到的,官方不推薦使用host屬性,推薦使用@HostBinding裝飾器來實現host的關於dom屬性相關的功能。

還是以MatTable爲例,需要做一下改造來實現相應的功能:

@Component({
 moduleId: module.id,
 selector: 'mat-table, table[mat-table]',
 exportAs: 'matTable',
 template: CDK_TABLE_TEMPLATE,
 styleUrls: ['table.css'],
//   host: {
//     'class': 'mat-table',
//   },
 providers: [{provide: CdkTable, useExisting: MatTable}],
 encapsulation: ViewEncapsulation.None,
 // See note on CdkTable for explanation on why this uses the default change detection strategy.
 // tslint:disable-next-line:validate-decorators
 changeDetection: ChangeDetectionStrategy.Default,
})
export class MatTable<T> extends CdkTable<T> {
 /** Overrides the sticky CSS class set by the `CdkTable`. */
 protected stickyCssClass = 'mat-table-sticky';

 // 使用HostBinding裝飾器
 @HostBinding('class.mat-table') clz = true;
}





















方法三:Renderer2

Renderer2是Angular的渲染引擎,我們可以通過它來爲自定義組件添加默認樣式。

還是以MatTable爲例,需要做一下改造來實現相應的功能:

@Component({
 moduleId: module.id,
 selector: 'mat-table, table[mat-table]',
 exportAs: 'matTable',
 template: CDK_TABLE_TEMPLATE,
 styleUrls: ['table.css'],
//   host: {
//     'class': 'mat-table',
//   },
 providers: [{provide: CdkTable, useExisting: MatTable}],
 encapsulation: ViewEncapsulation.None,
 // See note on CdkTable for explanation on why this uses the default change detection strategy.
 // tslint:disable-next-line:validate-decorators
 changeDetection: ChangeDetectionStrategy.Default,
})
export class MatTable<T> extends CdkTable<T> {
 /** Overrides the sticky CSS class set by the `CdkTable`. */
 protected stickyCssClass = 'mat-table-sticky';

 constructor(render: Renderer2, eleRef: ElementRef) {
     render.addClass(eleRef.nativeElement, 'mat-table');
 }
}






















總結

很多時候,實現一個功能的方法有很多,需要我們不斷的去挖掘,去思考。條條大路通羅馬,只要努力了總會有收穫。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章