Vue3卡片(Card)
2026/8/29 13:50:28 网站建设 项目流程

效果如下图:




在线预览

APIs

Card

参数说明类型默认值
width卡片宽度,单位pxnumber | string‘auto’
bordered是否有边框booleantrue
size卡片的尺寸‘small’ | ‘middle’ | ‘large’‘middle’
hoverable鼠标移过时可浮起booleanfalse
loading当卡片内容还在加载中时,可以用loading展示一个占位booleanfalse
skeletonProps加载中时,骨架屏的属性配置,参考 Skeleton Propsobject{}
title卡片标题string | slotundefined
extra卡片右上角的操作区域string | slotundefined
headStyle自定义标题区域样式CSSProperties{}
bodyStyle自定义内容区域样式CSSProperties{}

Slots

名称说明类型
title自定义卡片标题v-slot:title
extra自定义右上角的操作区域v-slot:extra

创建卡片组件Card.vue

其中引入使用了以下组件和工具函数:

<script setup lang="ts">import{computed}from'vue'importtype{CSSProperties}from'vue'importSkeletonfrom'components/skeleton'import{useSlotsExist}from'components/utils'exportinterfaceProps{width?:number|string// 卡片宽度,单位 pxbordered?:boolean// 是否有边框size?:'small'|'middle'|'large'// 卡片的尺寸hoverable?:boolean// 鼠标移过时可浮起loading?:boolean// 当卡片内容还在加载中时,可以用 loading 展示一个占位skeletonProps?:object// 加载中时,骨架屏的属性配置,参考 Skeleton Propstitle?:string// 卡片标题 string | slotextra?:string// 卡片右上角的操作区域 string | slotheadStyle?:CSSProperties// 自定义标题区域样式bodyStyle?:CSSProperties// 自定义内容区域样式}constprops=withDefaults(defineProps<Props>(),{width:'auto',bordered:true,size:'middle',hoverable:false,loading:false,skeletonProps:()=>({}),title:undefined,extra:undefined,headStyle:()=>({}),bodyStyle:()=>({})})constslotsExist=useSlotsExist(['title','extra'])constcardWidth=computed(()=>{if(typeofprops.width==='number'){return`${props.width}px`}returnprops.width})constshowHeader=computed(()=>{returnslotsExist.title||slotsExist.extra||props.title||props.extra})constshowTitle=computed(()=>{returnslotsExist.title||props.title})constshowExtra=computed(()=>{returnslotsExist.extra||props.extra})</script><template><divclass="card-wrap":class="{'card-bordered':bordered,'card-small':size==='small','card-middle':size==='middle','card-large':size==='large','card-hoverable':hoverable}":style="`width: ${cardWidth};`"><divclass="card-head":style="headStyle"v-if="showHeader"><divclass="head-wrapper"><div v-if="showTitle"class="head-title"><slot name="title">{{title}}</slot></div><div v-if="showExtra"class="head-extra"><slot name="extra">{{extra}}</slot></div></div></div><divclass="card-body":style="bodyStyle"><Skeleton:title="false":loading="loading"v-bind="skeletonProps"><slot></slot></Skeleton></div></div></template><style lang="less"scoped>.card-wrap{font-size:14px;color:rgba(0,0,0,0.88);line-height:1.5714285714285714;position:relative;background:#ffffff;border-radius:8px;text-align:left;transition:width0.2s;.card-head{display:flex;justify-content:center;flex-direction:column;margin-bottom:-1px;color:rgba(0,0,0,0.88);font-weight:600;background:transparent;border-bottom:1px solid #f0f0f0;border-radius:8px 8px00;transition:all0.2s;.head-wrapper{width:100%;display:flex;align-items:center;gap:8px;.head-title{display:inline-block;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.head-extra{margin-left:auto;font-weight:normal;font-size:14px;transition:font-size0.2s;}}}.card-body{border-radius:008px 8px;transition:padding0.2s;}}.card-bordered{border:1px solid #f0f0f0;}.card-small{.card-head{min-height:38px;padding:012px;font-size:14px;}.card-body{padding:12px;}}.card-middle{.card-head{min-height:56px;padding:024px;font-size:16px;}.card-body{padding:24px;}}.card-large{font-size:16px;.card-head{min-height:74px;padding:036px;font-size:18px;.head-wrapper.head-extra{font-size:16px;}}.card-body{padding:36px;}}.card-hoverable{cursor:pointer;transition:box-shadow0.2s,border-color0.2s;&:hover{box-shadow:01px 2px-2pxrgba(0,0,0,0.16),03px 6px0rgba(0,0,0,0.12),05px 12px 4pxrgba(0,0,0,0.09);}}</style>

在要使用的页面引入

其中引入使用了以下组件:

<script setup lang="ts">importCardfrom'./Card.vue'import{ref}from'vue'constsizeOptions=[{label:'small',value:'small'},{label:'middle',value:'middle'},{label:'large',value:'large'}]constcardWidth={small:240,middle:300,large:360}constsize=ref('middle')constloading=ref(true)</script><template><div><h1>{{$route.name}}{{$route.meta.title}}</h1><h2class="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><h2class="mt30 mb10">在灰色背景上使用无边框的卡片</h2><div style="display: inline-block; background: #ececec; padding: 30px; border-radius: 8px"><Card title="Card title":bordered="false":width="300"><p>Card content</p><p>Card content</p><p>Card content</p></Card></div><h2class="mt30 mb10">简洁卡片</h2><Card hoverable:width="300"><p>Card content</p><p>Card content</p><p>Card content</p></Card><h2class="mt30 mb10">三种尺寸</h2><Space vertical><Radio:options="sizeOptions"v-model:value="size"button button-style="solid"/><Card:size="size":title="`${size.toUpperCase()} size card`":width="cardWidth[size as keyof typeof cardWidth]"><template #extra><a href="#">more</a></template><p>card content</p><p>card content</p><p>card content</p></Card></Space><h2class="mt30 mb10">鼠标移过时可浮起</h2><Card hoverable title="Card title":width="300"><p>Card content</p><p>Card content</p><p>Card content</p></Card><h2class="mt30 mb10">预加载卡片</h2><Space vertical><Space align="center">Loading State:<Switch v-model="loading"/></Space><Card:loading="loading"title="Card title":width="300"><p>Card content</p><p>Card content</p><p>Card content</p></Card></Space><h2class="mt30 mb10">自定义样式</h2><Card title="Default size card":width="300":headStyle="{ fontSize: '18px', color: '#fff', backgroundColor: '#1677ff' }":bodyStyle="{ fontSize: '16px', color: '#fff', backgroundColor: '#52c41a' }"><template #extra><a href="#">more</a></template><p>card content</p><p>card content</p><p>card content</p></Card><h2class="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><h2class="mt30 mb10">栅格卡片</h2><div style="background-color: #ececec; padding: 20px; border-radius: 8px"><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></div></template>

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

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

立即咨询