You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将可折叠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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:02:51