如何将可折叠mat-card封装为带自定义子标签的Angular组件?
封装可折叠自定义Mat-Card组件
1. 定义子标签组件
先创建my-card-title、my-card-content这类子组件,它们作为内容投影的容器,无需复杂逻辑:
my-card-title.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-card-title', template: `<ng-content></ng-content>`, styles: [` /* 可自定义标题样式,比如字体大小、颜色 */ display: flex; align-items: center; `] }) export class MyCardTitleComponent {}
my-card-content.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-card-content', template: `<ng-content></ng-content>`, styles: [` /* 自定义内容区域样式 */ padding-top: 12px; `] }) export class MyCardContentComponent {}
2. 实现主组件my-card
主组件负责折叠逻辑,通过内容投影接收子标签内容,内部维护折叠状态:
my-card.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-card', templateUrl: './my-card.component.html', styleUrls: ['./my-card.component.css'] }) export class MyCardComponent { collapsed = false; toggleCollapse() { this.collapsed = !this.collapsed; } }
my-card.component.html
<mat-card> <mat-card-header (click)="toggleCollapse()" style="cursor: pointer;"> <mat-card-title> <ng-content select="my-card-title"></ng-content> <mat-icon style="margin-left: 8px;">{{ collapsed ? 'expand_more' : 'expand_less' }}</mat-icon> </mat-card-title> </mat-card-header> <mat-card-content *ngIf="!collapsed"> <ng-content select="my-card-content"></ng-content> </mat-card-content> </mat-card>
my-card.component.css
/* 可自定义卡片整体样式 */ mat-card { margin-bottom: 16px; }
3. 注册组件到模块
在你的功能模块(如MyCardModule)中声明并导出所有组件,方便全局使用:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatCardModule } from '@angular/material/card'; import { MatIconModule } from '@angular/material/icon'; import { MyCardComponent } from './my-card.component'; import { MyCardTitleComponent } from './my-card-title.component'; import { MyCardContentComponent } from './my-card-content.component'; @NgModule({ declarations: [ MyCardComponent, MyCardTitleComponent, MyCardContentComponent ], imports: [ CommonModule, MatCardModule, MatIconModule ], exports: [ MyCardComponent, MyCardTitleComponent, MyCardContentComponent ] }) export class MyCardModule {}
4. 使用自定义组件
在任意模板中直接调用,每个卡片独立维护折叠状态,无需重复定义变量:
<my-card> <my-card-title>用户信息</my-card-title> <my-card-content> <p>姓名:张三</p> <p>邮箱:zhangsan@example.com</p> </my-card-content> </my-card> <my-card> <my-card-title>订单详情</my-card-title> <my-card-content> <p>订单号:NO.20240518001</p> <p>状态:已发货</p> </my-card-content> </my-card>
核心逻辑说明
- 子标签通过
ng-content的select属性实现精准内容投影,主组件能识别并渲染对应区域的内容。 - 每个
my-card内部自带collapsed变量,父组件无需维护多个状态,彻底解决代码重复问题。 - 若需扩展更多子标签(如
my-card-actions),只需新增对应子组件,再在主组件模板中添加<ng-content select="my-card-actions"></ng-content>即可。
内容的提问来源于stack exchange,提问作者assylias
相关产品推荐
相关产品推荐

