Vue3卡片(Card)

可自定义设置以下属性:

  • 卡片宽度(width),类型:number | string,默认 'auto'
  • 是否有边框(bordered),类型:boolean,默认 true
  • 卡片右上角的操作区域(extra),类型:string | slot,默认 ''
  • 卡片的尺寸(size),类型:'default' | 'small',默认:'default'
  • 卡片标题(title),类型:string | slot,默认 ''
  • 标题区域自定义样式(headStyle),类型:CSSProperties,默认:{}
  • 内容区域自定义样式(bodyStyle),类型:CSSProperties,默认:{}

效果如下图:在线预览




创建卡片组件Card.vue

ts 复制代码
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { CSSProperties } from 'vue'
interface Props {
  width?: number|string // 卡片宽度
  bordered?: boolean // 是否有边框
  extra?: string // 卡片右上角的操作区域 string | slot
  size?: 'default'|'small' // 卡片的尺寸
  title?: string // 卡片标题 string | slot
  headStyle?: CSSProperties //	标题区域自定义样式
  bodyStyle?: CSSProperties // 内容区域自定义样式
}
const props = withDefaults(defineProps<Props>(), {
  width: 'auto',
  bordered: true,
  extra: '',
  size: 'default',
  title: '',
  headStyle: () => { return {} },
  bodyStyle: () => { return {} }
})
const cardWidth = computed(() => {
  if (typeof props.width === 'number') {
    return props.width + 'px'
  }
  return props.width
})
const headRef = ref() // 声明一个同名的模板引用
const showHead = ref(1)
onMounted(() => {
  showHead.value = headRef.value.offsetHeight
})
</script>
<template>
  <div
    class="m-card"
    :class="{'bordered': bordered, 'm-small-card': size === 'small'}"
    :style="`width: ${cardWidth};`">
    <div class="m-card-head" :style="headStyle" v-if="showHead">
      <div class="m-head-wrapper" ref="headRef">
        <div class="u-title">
          <slot name="title">{{ title }}</slot>
        </div>
        <div class="u-extra">
          <slot name="extra">{{ extra }}</slot>
        </div>
      </div>
    </div>
    <div class="m-card-body" :style="bodyStyle">
      <slot></slot>
    </div>
  </div>
</template>
<style lang="less" scoped>
.bordered {
  border: 1px solid #f0f0f0;
}
.m-card {
  font-size: 14px;
  color: rgba(0, 0, 0, 0.88);
  line-height: 1.5714285714285714;
  position: relative;
  background: #ffffff;
  border-radius: 8px;
  text-align: left;
  .m-card-head {
    display: flex;
    justify-content: center;
    flex-direction: column;
    min-height: 56px;
    margin-bottom: -1px;
    padding: 0 24px;
    color: rgba(0, 0, 0, 0.88);
    font-weight: 600;
    font-size: 16px;
    background: transparent;
    border-bottom: 1px solid #f0f0f0;
    border-radius: 8px 8px 0 0;
    .m-head-wrapper {
      width: 100%;
      display: flex;
      align-items: center;
      .u-title {
        display: inline-block;
        flex: 1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .u-extra {
        margin-inline-start: auto;
        font-weight: normal;
        font-size: 14px;
      }
    }
  }
  .m-card-body {
    padding: 24px;
    border-radius: 0 0 8px 8px;
  }
}
.m-small-card {
  .m-card-head {
    min-height: 38px;
    padding: 0 12px;
    font-size: 14px;
  }
  .m-card-body {
    padding: 12px;
  }
}
</style>

在要使用的页面引入

其中引入使用了 Vue3栅格(Grid)

ts 复制代码
<script setup lang="ts">
import Card from './Card.vue'
</script>
<template>
  <div>
    <h1>Card 卡片</h1>
    <h2 class="mt30 mb10">基本使用</h2>
    <Card title="Default size card" :width="300">
      <template #extra><a href="#">more</a></template>
      <p>card content</p>
      <p>card content</p>
      <p>card content</p>
    </Card>
    <h2 class="mt30 mb10">小尺寸卡片</h2>
    <Card size="small" title="Small size card" :width="300">
      <template #extra><a href="#">more</a></template>
      <p>card content</p>
      <p>card content</p>
      <p>card content</p>
    </Card>
    <h2 class="mt30 mb10">在灰色背景上使用无边框的卡片</h2>
    <div style="display: inline-block; background: #ececec; padding: 30px;">
      <Card title="Card title" :bordered="false" :width="300">
        <p>Card content</p>
        <p>Card content</p>
        <p>Card content</p>
      </Card>
    </div>
    <h2 class="mt30 mb10">自定义标题和内容区域样式</h2>
    <Card
      title="Default size card"
      :width="300"
      :headStyle="{ fontSize: '18px', color: '#fff', backgroundColor: '#52c41a'}"
      :bodyStyle="{ fontSize: '16px', color: '#fff', backgroundColor: '#faad14'}">
      <template #extra><a href="#">more</a></template>
      <p>card content</p>
      <p>card content</p>
      <p>card content</p>
    </Card>
    <h2 class="mt30 mb10">内部卡片</h2>
    <Card title="Card title" :width="360">
      <p style="font-size: 14px; color: rgba(0, 0, 0, 0.85); margin-bottom: 16px; font-weight: 500;">
        Group title
      </p>
      <Card title="Inner card title">
        <template #extra>
          <a href="#">More</a>
        </template>
        Inner Card content
      </Card>
      <Card title="Inner card title" :style="{ marginTop: '16px' }">
        <template #extra>
          <a href="#">More</a>
        </template>
        Inner Card content
      </Card>
    </Card>
    <h2 class="mt30 mb10">栅格卡片</h2>
    <div style="background-color: #ececec; padding: 20px;">
      <Row :gutter="16">
        <Col :span="8">
          <Card title="Card title" :bordered="false">
            <p>card content</p>
          </Card>
        </Col>
        <Col :span="8">
          <Card title="Card title" :bordered="false">
            <p>card content</p>
          </Card>
        </Col>
        <Col :span="8">
          <Card title="Card title" :bordered="false">
            <p>card content</p>
          </Card>
        </Col>
      </Row>
    </div>
    <h2 class="mt30 mb10">简洁卡片</h2>
    <Card :width="300">
      <p>Card content</p>
      <p>Card content</p>
      <p>Card content</p>
    </Card>
  </div>
</template>
相关推荐
RuoyiOffice3 天前
SpringBoot+Vue3+Onlyoffice 企业文件生命周期:上传、业务关联、权限、版本与安全清理
spring boot·vue3·文件管理·对象存储·权限控制·ruoyi office·附件管理
格数致用6 天前
03- Luckysheet与Vue3+Electron集成实战指南
electron·vue3·luckysheet
陪我一起学编程12 天前
vue3笔记
前端·webpack·vue3·vite·脚手架·vue3笔记·组件式
Json____15 天前
家居装修 AI 智能咨询助手:让装修咨询从“大海捞针“变成“一问即答“
java·后端·vue3·it学习·wwwoop.com
liangshanbo121515 天前
面试题:什么是 Reflect?它解决了什么问题?
vue3·reflect
RuoyiOffice16 天前
SpringBoot3+Vue3 低代码业务表单:从拖拽设计、独立建表到审批与数据查询
spring boot·vue3·数据建模·flowable·版本管理·低代码表单·ruoyi office
RuoyiOffice16 天前
SpringBoot3 企业薪酬核算:考勤、绩效与薪资规则如何算出一张可解释的工资单
spring boot·vue3·规则引擎·hrm·ruoyi office·薪酬核算·薪资试算
RuoyiOffice22 天前
2026最推荐基于SpringBoot+Vue3的项目管理经营一体化:从商机、合同、任务与工时走到回款和利润
spring boot·项目管理·vue3·crm·合同管理·ruoyi office·项目经营
RuoyiOffice23 天前
SpringBoot+Vue3 节日主题换肤实战:一条参数换全站配色,节后自动还原
spring boot·vue3·spring boot 3·vben admin·ruoyi office·节日主题·换肤方案
RuoyiOffice25 天前
SpringBoot3+Vue3 流程抄送已读:打开详情消红点,待办与知会怎么分开
spring boot·vue3·flowable·spring boot 3·ruoyi office·流程抄送·已读回执