Skip to content

卡片组件

卡片组件提供了灵活的容器布局,支持头部、内容、底部等区域的自定义配置,是构建界面的基础组件。

导入

typescript
import { DuxCard } from '@duxweb/dvha-pro'

组件总览

DVHA Pro 提供以下卡片组件:

  • DuxCard - 通用卡片容器组件

DuxCard 通用卡片容器

通用卡片容器组件,提供了灵活的布局结构,支持头部、内容、底部区域的自定义,以及多种样式配置。

属性

属性名类型默认值说明
size'none' | 'small' | 'medium' | 'large''none'整体内边距尺寸
headerSize'none' | 'small' | 'medium' | 'large''medium'头部内边距尺寸
footerSize'none' | 'small' | 'medium' | 'large''medium'底部内边距尺寸
contentSize'none' | 'small' | 'medium' | 'large''medium'内容区域内边距尺寸
dividebooleanfalse是否显示分割线
headerClassstring''头部自定义样式类
footerClassstring''底部自定义样式类
contentClassstring''内容自定义样式类
titlestring''卡片标题
descriptionstring''卡片描述
borderedbooleanfalse是否显示边框
shadowbooleantrue是否显示阴影
headerBorderedbooleanfalse头部是否显示边框
footerBorderedbooleanfalse底部是否显示边框
type'default' | 'elevated' | 'inverted''default'卡片类型

插槽

插槽名说明
default主要内容区域
header头部内容
footer底部内容
headerExtra头部额外内容

基础用法

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
</script>

<template>
  <!-- 基础卡片 -->
  <DuxCard title="基础卡片" description="这是一个基础的卡片组件">
    <p>这里是卡片的主要内容区域</p>
  </DuxCard>

  <!-- 自定义头部和底部 -->
  <DuxCard>
    <template #header>
      <div class="flex items-center justify-between">
        <h3 class="text-lg font-medium">
          自定义头部
        </h3>
        <button class="text-primary">
          操作
        </button>
      </div>
    </template>

    <p>卡片内容</p>

    <template #footer>
      <div class="flex justify-end gap-2">
        <button class="px-4 py-2 text-sm border rounded">
          取消
        </button>
        <button class="px-4 py-2 text-sm bg-primary text-white rounded">
          确认
        </button>
      </div>
    </template>
  </DuxCard>
</template>

不同尺寸

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
</script>

<template>
  <!-- 无内边距 -->
  <DuxCard title="无内边距" size="none">
    <div class="p-4 bg-gray-50">
      自定义内边距的内容
    </div>
  </DuxCard>

  <!-- 小尺寸 -->
  <DuxCard title="小尺寸" size="small">
    <p>小尺寸内边距的卡片</p>
  </DuxCard>

  <!-- 中等尺寸 -->
  <DuxCard title="中等尺寸" size="medium">
    <p>中等尺寸内边距的卡片</p>
  </DuxCard>

  <!-- 大尺寸 -->
  <DuxCard title="大尺寸" size="large">
    <p>大尺寸内边距的卡片</p>
  </DuxCard>
</template>

不同类型

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
</script>

<template>
  <!-- 默认类型 -->
  <DuxCard title="默认卡片" type="default">
    <p>这是默认类型的卡片</p>
  </DuxCard>

  <!-- 浮起类型 -->
  <DuxCard title="浮起卡片" type="elevated">
    <p>这是浮起类型的卡片,具有更明显的阴影效果</p>
  </DuxCard>

  <!-- 反色类型 -->
  <DuxCard title="反色卡片" type="inverted">
    <p>这是反色类型的卡片,适用于深色主题</p>
  </DuxCard>
</template>

边框和分割线

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
</script>

<template>
  <!-- 带边框的卡片 -->
  <DuxCard title="带边框卡片" bordered>
    <p>这是带有边框的卡片</p>
  </DuxCard>

  <!-- 带分割线的卡片 -->
  <DuxCard divide>
    <template #header>
      <h3>头部区域</h3>
    </template>

    <p>内容区域</p>

    <template #footer>
      <p>底部区域</p>
    </template>
  </DuxCard>

  <!-- 头部和底部边框 -->
  <DuxCard header-bordered footer-bordered>
    <template #header>
      <h3>带边框的头部</h3>
    </template>

    <p>内容区域</p>

    <template #footer>
      <p>带边框的底部</p>
    </template>
  </DuxCard>
</template>

复杂布局示例

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
import { NButton, NTag } from 'naive-ui'
import { ref } from 'vue'

const stats = ref([
  { label: '总访问量', value: '12,345' },
  { label: '今日访问', value: '1,234' },
  { label: '用户数', value: '567' },
  { label: '转化率', value: '12.3%' }
])
</script>

<template>
  <!-- 统计卡片 -->
  <DuxCard title="网站统计" description="最近30天的数据统计" divide>
    <template #headerExtra>
      <NTag type="success" size="small">
        实时
      </NTag>
    </template>

    <div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
      <div v-for="stat in stats" :key="stat.label" class="text-center">
        <div class="text-2xl font-bold text-primary">
          {{ stat.value }}
        </div>
        <div class="text-sm text-muted">
          {{ stat.label }}
        </div>
      </div>
    </div>

    <template #footer>
      <div class="flex justify-between items-center">
        <span class="text-sm text-muted">最后更新:2024-01-01 12:00</span>
        <NButton size="small">
          查看详情
        </NButton>
      </div>
    </template>
  </DuxCard>

  <!-- 用户信息卡片 -->
  <DuxCard size="none" bordered>
    <template #header>
      <div class="flex items-center gap-3 p-4">
        <img src="/avatar.jpg" alt="用户头像" class="w-12 h-12 rounded-full">
        <div>
          <h3 class="font-medium">
            张三
          </h3>
          <p class="text-sm text-muted">
            高级开发工程师
          </p>
        </div>
      </div>
    </template>

    <div class="px-4 pb-4">
      <div class="space-y-2">
        <div class="flex justify-between">
          <span class="text-muted">邮箱</span>
          <span>zhangsan@example.com</span>
        </div>
        <div class="flex justify-between">
          <span class="text-muted">部门</span>
          <span>技术部</span>
        </div>
        <div class="flex justify-between">
          <span class="text-muted">入职时间</span>
          <span>2023-01-01</span>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="flex gap-2 p-4 pt-0">
        <NButton size="small" block>
          发送消息
        </NButton>
        <NButton size="small" type="primary" block>
          查看详情
        </NButton>
      </div>
    </template>
  </DuxCard>
</template>

表单卡片

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
import { NButton, NInput, NSelect } from 'naive-ui'
import { ref } from 'vue'

const formData = ref({
  name: '',
  email: '',
  department: ''
})

const departments = [
  { label: '技术部', value: 'tech' },
  { label: '产品部', value: 'product' },
  { label: '设计部', value: 'design' }
]
</script>

<template>
  <DuxCard title="用户信息" description="请填写完整的用户信息" divide>
    <div class="space-y-4">
      <div>
        <label class="block text-sm font-medium mb-1">姓名</label>
        <NInput v-model:value="formData.name" placeholder="请输入姓名" />
      </div>

      <div>
        <label class="block text-sm font-medium mb-1">邮箱</label>
        <NInput v-model:value="formData.email" placeholder="请输入邮箱" />
      </div>

      <div>
        <label class="block text-sm font-medium mb-1">部门</label>
        <NSelect
          v-model:value="formData.department"
          :options="departments"
          placeholder="请选择部门"
        />
      </div>
    </div>

    <template #footer>
      <div class="flex justify-end gap-2">
        <NButton>取消</NButton>
        <NButton type="primary">
          保存
        </NButton>
      </div>
    </template>
  </DuxCard>
</template>

图片卡片

vue
<script setup>
import { DuxCard } from '@duxweb/dvha-pro'
import { NButton, NTag } from 'naive-ui'
</script>

<template>
  <DuxCard size="none" class="overflow-hidden">
    <template #header>
      <div class="relative">
        <img
          src="/product-image.jpg"
          alt="产品图片"
          class="w-full h-48 object-cover"
        >
        <div class="absolute top-2 right-2">
          <NTag type="error" size="small">
            热销
          </NTag>
        </div>
      </div>
    </template>

    <div class="p-4">
      <h3 class="text-lg font-medium mb-2">
        产品名称
      </h3>
      <p class="text-muted text-sm mb-3">
        这里是产品的详细描述信息,介绍产品的主要特点和优势。
      </p>
      <div class="flex items-center justify-between">
        <span class="text-2xl font-bold text-red-500">¥299</span>
        <span class="text-sm text-muted line-through">¥399</span>
      </div>
    </div>

    <template #footer>
      <div class="flex gap-2 p-4 pt-0">
        <NButton block>
          加入购物车
        </NButton>
        <NButton type="primary" block>
          立即购买
        </NButton>
      </div>
    </template>
  </DuxCard>
</template>

设计特性

灵活的布局结构

  • 头部区域 - 支持标题、描述和额外操作
  • 内容区域 - 主要内容展示区域
  • 底部区域 - 操作按钮或补充信息

丰富的样式配置

  • 尺寸控制 - 支持不同区域的内边距配置
  • 视觉效果 - 边框、阴影、分割线等视觉元素
  • 主题适配 - 支持不同的卡片类型和主题

响应式设计

  • 自动适配不同屏幕尺寸
  • 支持移动端和桌面端的最佳显示效果
  • 灵活的网格布局支持

最佳实践

内容组织

  • 使用清晰的标题和描述
  • 合理组织内容层次结构
  • 避免在单个卡片中放置过多信息

样式一致性

  • 在同一页面中保持卡片样式的一致性
  • 合理使用边框和分割线
  • 选择合适的内边距尺寸

交互设计

  • 在需要时提供悬停效果
  • 合理放置操作按钮
  • 使用适当的视觉反馈

常见问题

Q: 如何自定义卡片的背景色?

A: 可以通过 CSS 类名或内联样式来自定义背景色,也可以使用 type 属性选择预设的主题。

Q: 如何控制卡片的宽度和高度?

A: 卡片的尺寸由其容器控制,可以通过 CSS 类名或网格布局来设置宽度和高度。

Q: 如何在卡片中嵌套其他组件?

A: 卡片组件支持任意内容的嵌套,可以在插槽中放置其他组件、表单元素或自定义内容。

Q: 如何实现卡片的响应式布局?

A: 使用 CSS Grid 或 Flexbox 布局,结合响应式断点类名来实现不同屏幕下的布局效果。