将含mat-expansion-panel的组件加入mat-accordion时样式异常求助
问题描述
将包含mat-expansion-panel的自定义子组件放入mat-accordion后,功能正常但样式不符合预期,无法达到Angular Material v14官方文档中的折叠面板样式。
父组件代码
<mat-accordion> <app-panel1></app-panel1> <app-panel2></app-panel2> </mat-accordion>
子组件(app-panel.html)代码
panel1与panel2结构一致:
<mat-expansion-panel (opened)="panelOpenState = true" (closed)="panelOpenState = false"> <mat-expansion-panel-header> <mat-panel-title> Title </mat-panel-title> <mat-panel-description> Description </mat-panel-description> </mat-expansion-panel-header> <ng-template matExpansionPanelContent> Content </ng-template> </mat-expansion-panel>
样式对比
- 当前样式:

- 期望样式(参考Angular Material v14官方文档):

原因及解决办法
问题根源
mat-accordion需要直接将mat-expansion-panel作为子元素,它会通过内容投影给直接子级的折叠面板添加mat-accordion-item等样式类。如果中间嵌套了自定义组件,这些样式无法正确继承,导致面板之间没有连贯的边框、圆角等样式。
方案1:移除自定义子组件包装
直接将mat-expansion-panel放在父组件的mat-accordion中:
<mat-accordion> <mat-expansion-panel (opened)="panelOpenState = true" (closed)="panelOpenState = false"> <mat-expansion-panel-header> <mat-panel-title> Panel1 Title </mat-panel-title> <mat-panel-description> Panel1 Description </mat-panel-description> </mat-expansion-panel-header> <ng-template matExpansionPanelContent> Panel1 Content </ng-template> </mat-expansion-panel> <mat-expansion-panel (opened)="panelOpenState = true" (closed)="panelOpenState = false"> <mat-expansion-panel-header> <mat-panel-title> Panel2 Title </mat-panel-title> <mat-panel-description> Panel2 Description </mat-panel-description> </mat-expansion-panel-header> <ng-template matExpansionPanelContent> Panel2 Content </ng-template> </mat-expansion-panel> </mat-accordion>
方案2:保留自定义子组件并传递样式上下文
如果需要复用自定义子组件,可通过HostBinding和注入MAT_ACCORDION来传递样式类:
- 子组件TS代码:
import { Component, HostBinding, Optional, Inject } from '@angular/core'; import { MAT_ACCORDION, MatAccordion } from '@angular/material/expansion'; @Component({ selector: 'app-panel', templateUrl: './app-panel.html', styleUrls: ['./app-panel.css'] }) export class AppPanelComponent { panelOpenState = false; constructor(@Optional() @Inject(MAT_ACCORDION) public accordion: MatAccordion) {} @HostBinding('class.mat-accordion-item') get isAccordionItem(): boolean { return !!this.accordion; } }
- 子组件HTML修改:
<mat-expansion-panel [accordion]="accordion" (opened)="panelOpenState = true" (closed)="panelOpenState = false"> <mat-expansion-panel-header> <mat-panel-title> Title </mat-panel-title> <mat-panel-description> Description </mat-panel-description> </mat-expansion-panel-header> <ng-template matExpansionPanelContent> Content </ng-template> </mat-expansion-panel>
内容的提问来源于stack exchange,提问作者Aditeya
相关产品推荐
相关产品推荐

