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>
相关推荐
知识分享小能手2 天前
Vue3 学习教程,从入门到精通,Axios 在 Vue 3 中的使用指南(37)
前端·javascript·vue.js·学习·typescript·vue·vue3
伍哥的传说2 天前
Mitt 事件发射器完全指南:200字节的轻量级解决方案
vue.js·react.js·vue3·mitt·组件通信·事件管理·事件发射器
尚学教辅学习资料2 天前
Vue3从入门到精通:5.2 Vue3构建工具与性能优化深度解析
性能优化·vue3·入门到精通
加班是不可能的,除非双倍日工资3 天前
css预编译器实现星空背景图
前端·css·vue3
har01d7 天前
【CSS3】录音中。。。
前端·css·vue.js·vue·vue3·css3
知识分享小能手8 天前
Vue3 学习教程,从入门到精通,Vue 3 + Tailwind CSS 全面知识点与案例详解(31)
前端·javascript·css·vue.js·学习·typescript·vue3
青柠代码录16 天前
【ElementPlus】深入探索ElementPlus:前端界面的全能组件库
前端·vue3·elementplus
知识分享小能手18 天前
Vue3 学习教程,从入门到精通,Vue3 中使用 Axios 进行 Ajax 请求的语法知识点与案例代码(23)
前端·javascript·vue.js·学习·ajax·vue·vue3
咔咔一顿操作19 天前
Vue 3 入门教程7 - 状态管理工具 Pinia
前端·javascript·vue.js·vue3
汪叽家的兔子羡20 天前
vue模块化导入
前端·javascript·vue.js·typescript·vue3·vue2·vite