Element Plus Card 组件完全指南:容器布局、阴影控制与源码级解析
2026/9/10 10:28:14 网站建设 项目流程

Element Plus Card 组件完全指南:容器布局、阴影控制与源码级解析

【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus

Element Plus 的 Card(卡片)组件用于将标题、正文、操作区域等信息整合进一个统一的卡片容器中,是构建仪表盘、内容列表与详情展示的常用基础组件。本文将基于 官方文档 全面讲解 Card 的三种典型用法、全部属性与插槽 API,并结合仓库内 组件实现源码、Props 类型定义 与 单元测试 深入剖析其底层渲染机制,读完即可在真实项目中灵活组合 header、body、footer 与阴影策略。

组件定位与基本结构

Card 的核心定位是"信息整合容器":它把标题、内容和操作区域封装在同一个视觉单元中。从 card.vue 的模板结构 可以看到,组件对外呈现为三段式结构:

  • header:可选头部区域,存在header属性或#header插槽时才渲染;
  • body:默认主体区域,始终渲染,承载默认插槽内容;
  • footer:可选底部区域,存在footer属性或#footer插槽时才渲染。

其中 header 与 footer 均为可选段,内容分发依赖具名插槽。整个根节点会根据shadow属性动态追加is-always-shadowis-hover-shadowis-never-shadow修饰类,对应 card.scss 中的状态样式。

基础用法:header、body 与 footer 三段式布局

基础场景下,Card 由标题、正文和底部操作区三部分组成。官方示例 docs/examples/card/basic.vue 展示了完整用法:

<template> <el-card style="max-width: 480px"> <template #header> <div class="card-header"> <span>Card name</span> </div> </template> <p v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</p> <template #footer>Footer content</template> </el-card> </template>

要点说明:

  • 头部通过#header具名插槽传入,可以是任意 DOM;也可以退而使用header字符串属性,两者等价(源码中v-if="$slots.header || header"同时监听插槽与属性,见 card.vue)。
  • 正文直接写在默认插槽中,本例循环渲染 4 条列表项。
  • 底部通过#footer具名插槽渲染"Footer content",适合放置操作按钮等元素。

单元测试 card.test.tsx 验证了两种头部传值方式:字符串属性header="I am header"与 VNode 插槽(包含 span 与 button 的复杂 DOM)都能正确渲染,说明插槽方式支持更灵活的富内容。

简单卡片:省略头部

当页面只需要纯内容展示时,可以省略头部区域。官方示例 docs/examples/card/simple.vue 是最精简形态:

<template> <el-card style="max-width: 480px"> <p v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</p> </el-card> </template>

此时既不传header属性也没有#header插槽,模板中的头部div不会渲染,卡片退化为纯 body 容器。footer 同理:只有提供对应属性或插槽时才渲染。

带图片的卡片:body-style 自定义正文样式

通过body-style属性可以为正文区域注入自定义 CSS 样式,从而让卡片承载图片、富媒体等更丰富的内容。官方示例 docs/examples/card/with-images.vue:

<template> <el-card style="max-width: 480px"> <template #header>Yummy hamburger</template> <img src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png" style="width: 100%" /> </el-card> </template>

body-style的类型为 Vue 的StyleValue。从 card.ts 的属性定义 可以看到,它通过definePropType<StyleValue>([String, Object, Array, Boolean])声明,即同时支持:

  • 字符串形式:如"font-size: 14px;"
  • 对象形式:如{ 'font-size': '14px' }
  • 数组形式:如[{ 'font-size': '14px' }, { color: 'blue' }],多个样式对象合并生效。

单元测试 对这三种形式逐一断言,验证最终都会正确落在.el-card__body元素的内联style属性上。此外,body-style的值会直接绑定到 body 的:style上(见 card.vue),因此也支持以;分隔的多条声明。

阴影控制:always、hover 与 never

shadow属性决定卡片阴影的显示时机,可选值为always(始终显示)、hover(悬停时显示)与never(从不显示),默认always。官方示例 docs/examples/card/shadow.vue:

<template> <div class="flex flex-wrap gap-4"> <el-card style="width: 480px" shadow="always">Always</el-card> <el-card style="width: 480px" shadow="hover">Hover</el-card> <el-card style="width: 480px" shadow="never">Never</el-card> </div> </template>

底层实现上,根节点类名由ns.is(${shadow || globalConfig?.shadow || 'always'}-shadow)计算(见 card.vue),再配合 card.scss 中.is-always-shadow.is-hover-shadow的 box-shadow 规则(hover模式还监听了:focus状态)。值得注意的细节:

  • shadow属性默认值为undefined,最终回落到'always'
  • 支持从ConfigProvider的全局配置中读取默认阴影策略(useGlobalConfig('card')),即项目级统一定义卡片阴影风格;
  • 单元测试 确认了类名拼接逻辑,例如shadow="always"会生成.is-always-shadow类。

完整 API 参考

以下 API 信息与官方文档 card.md 保持一致,并结合 card.ts 补充了更精确的类型细节。

Attributes 属性

名称说明类型默认值
header卡片标题,也接受通过slot#header传入的 DOM^[string]
footer ^(2.4.3)卡片底部内容,也接受通过slot#footer传入的 DOM^[string]
body-style卡片正文的 CSS 样式^[object]CSSProperties
header-class ^(2.9.8)卡片头部自定义类名^[string]
body-class ^(2.3.10)卡片正文自定义类名^[string]
footer-class ^(2.9.8)卡片底部自定义类名^[string]
shadow卡片阴影显示时机^[enum]always \| never \| hoveralways

补充说明:

  • headerfooter属性在 card.ts 中默认值为空字符串'',仅作纯文本兜底,富内容请优先使用具名插槽。
  • 三个*-class属性的类型为ClassValue,实际声明为[String, Array, Object, Boolean],因此支持字符串、数组(多类名)、对象(条件类名)三种写法。
  • 上述 class 属性在 card.vue 中分别拼接在.el-card__header.el-card__body.el-card__footer上,单元测试 已验证三个类名均正确挂载。

Slots 插槽

名称说明
default自定义默认内容
header卡片头部内容
footer卡片底部内容

样式定制要点

卡片样式基于 CSS 变量驱动,位于 packages/theme-chalk/src/card.scss。可通过覆盖变量实现主题定制:

  • card-padding:header/body/footer 的内边距基准值,header 与 footer 实际为padding - 2px
  • card-border-radius:卡片圆角;
  • card-border-color:边框与分隔线颜色;
  • card-bg-color:卡片背景色。

布局上,卡片根节点为flex-direction: column的纵向弹性布局,body 设置了flex-grow: 1overflow: auto,因此在弹性父容器中能自动撑满剩余高度并独立滚动,适合构建可滚动内容区。结合上述 CSS 变量即可无侵入地完成卡片圆角、间距与阴影深浅的品牌化定制。

实战小结

通过本文可以掌握 Element Plus Card 组件从"最小可用"到"富内容卡片"的完整路径:

  1. 基础三段式布局:#header+ 默认插槽 +#footer
  2. 精简形态:省略 header/footer 得到纯内容容器;
  3. 富媒体扩展:用body-style(字符串/对象/数组三种写法)定制正文样式;
  4. 交互反馈:用shadow三态(always/hover/never)控制阴影时机,并结合 ConfigProvider 实现全局默认阴影策略;
  5. 精细定制:通过header-classbody-classfooter-class挂载自定义类,配合 SCSS 变量统一主题。

相关源码与示例可进一步查阅:组件模板与逻辑、Props 定义、单元测试、样式源码 以及 完整示例目录。

【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询