Skip to content

Card ​

17:06

Description ​

Groups a header, body and footer into one consistently styled card. The header is built from title / sub-title plus an optional thumb; the body and footer are filled by the default / body / foot slots, and a head slot replaces the built-in header entirely. Rounded corners, an outer shadow and a border are supported.

Compatibility ​

PlatformSupport
App✅ Supported
H5✅ Supported
WeChat Mini Program✅ Supported

Examples ​

Basic Usage ​

Configure the head title and sub-title via title / sub-title, and fill the body with the default slot.

View source
vue
<template>
    <ux-card title="卡片标题" sub-title="副标题" @click="onClick">
        <text class="body-text">卡片内容区域,支持自定义主体插槽,头部可配置标题与副标题。</text>
    </ux-card>
</template>

<script setup lang="uts">
const onClick = (index: string | number) => {
    console.log('card click:', index);
};
</script>

<style scoped>
.body-text {
    font-size: 13px;
    color: #909399;
    line-height: 20px;
}
</style>

Thumbnail thumb ​

Show a thumbnail on the left of the title via thumb, and control whether it is circular via thumb-circle.

View source
vue
<template>
    <ux-card
        title="带缩略图"
        sub-title="圆角头像"
        thumb="https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png"
        :thumb-circle="true"
    >
        <text class="body-text">通过 thumb 属性在标题左侧显示缩略图。</text>
    </ux-card>
</template>

<style scoped>
.body-text {
    font-size: 13px;
    color: #909399;
    line-height: 20px;
}
</style>

Custom Slots ​

Customize the head and foot via head / foot slots, fill the body via the default slot, and compose a feed-style card with text and images.

View source
vue
<template>
    <ux-card :border-radius="14" box-shadow="0 2px 12px rgba(0, 0, 0, 0.06)">
        <template #head>
            <view class="feed-head">
                <text class="feed-title">设计分享圈</text>
                <text class="feed-follow">+ 关注</text>
            </view>
        </template>
        <view class="feed-author">
            <image class="feed-avatar" src="https://picsum.photos/seed/card-avatar/72/72" mode="aspectFill" />
            <view class="feed-meta">
                <text class="feed-name">uView 设计</text>
                <text class="feed-time">3分钟前</text>
            </view>
        </view>
        <text class="feed-content">今晚分享一套新的配色方案,主打暖橙渐变,适合电商促销场景……</text>
        <image class="feed-image" src="https://picsum.photos/seed/card-post/600/360" mode="widthFix" />
        <template #foot>
            <view class="feed-actions">
                <text class="feed-action">点赞 128</text>
                <text class="feed-action">评论 32</text>
                <text class="feed-action">转发 12</text>
            </view>
        </template>
    </ux-card>
</template>

<style scoped>
.feed-head {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}
.feed-title {
    font-size: 15px;
    font-weight: bold;
    color: #303133;
}
.feed-follow {
    font-size: 13px;
    color: #2979ff;
}
.feed-author {
    display: flex;
    flex-direction: row;
    align-items: center;
    margin-bottom: 10px;
}
.feed-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    margin-right: 10px;
}
.feed-meta {
    display: flex;
    flex-direction: column;
}
.feed-name {
    font-size: 14px;
    color: #303133;
    font-weight: bold;
}
.feed-time {
    font-size: 12px;
    color: #909399;
    margin-top: 2px;
}
.feed-content {
    font-size: 14px;
    color: #606266;
    line-height: 21px;
    margin-bottom: 12px;
}
.feed-image {
    width: 100%;
    border-radius: 8px;
}
.feed-actions {
    display: flex;
    flex-direction: row;
    align-items: center;
}
.feed-action {
    font-size: 13px;
    color: #909399;
    margin-right: 28px;
}
</style>

Shadow box-shadow ​

Add an outer shadow to the card via box-shadow, as a string.

View source
vue
<template>
    <ux-card title="数据概览" box-shadow="0 6px 18px rgba(0, 0, 0, 0.08)" :border-radius="12">
        <view class="stats">
            <view class="stat">
                <text class="stat-num">128</text>
                <text class="stat-label">今日访问</text>
            </view>
            <view class="stat-divider" />
            <view class="stat">
                <text class="stat-num">3.2w</text>
                <text class="stat-label">累计订单</text>
            </view>
            <view class="stat-divider" />
            <view class="stat">
                <text class="stat-num">209</text>
                <text class="stat-label">会员数</text>
            </view>
        </view>
    </ux-card>
</template>

<style scoped>
.stats {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 4px 0 2px;
}
.stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 1;
}
.stat-num {
    font-size: 20px;
    font-weight: bold;
    color: #303133;
}
.stat-label {
    font-size: 12px;
    color: #909399;
    margin-top: 4px;
}
.stat-divider {
    width: 1px;
    height: 30px;
    background-color: #e4e7ed;
}
</style>

Rounded Corners border-radius ​

Set the overall border radius of the card via border-radius, in px.

View source
vue
<template>
    <ux-card title="自定义圆角" :border-radius="15">
        <text class="body-text">通过 border-radius 属性调整卡片圆角,0 为直角。</text>
    </ux-card>
</template>

<style scoped>
.body-text {
    font-size: 13px;
    color: #909399;
    line-height: 20px;
}
</style>

Border border ​

Control whether to show the card outer border via border.

View source
vue
<template>
    <ux-card title="显示边框" sub-title="带边框" :border="true">
        <text class="body-text">通过 border 属性显示卡片外部边框。</text>
    </ux-card>
</template>

<style scoped>
.body-text {
    font-size: 13px;
    color: #909399;
    line-height: 20px;
}
</style>

Full Width full ​

When full=true, the card leaves no gap on both sides, with left/right margin of 0.

View source
vue
<template>
    <ux-card title="全屏卡片" sub-title="无间距" :full="true" :border="true">
        <text class="body-text">full=true 时卡片与屏幕两侧不留空隙。</text>
    </ux-card>
</template>

<style scoped>
.body-text {
    font-size: 13px;
    color: #909399;
    line-height: 20px;
}
</style>

API ​

Props ​

PropertyDescriptionTypeDefaultVersion
customStyleCustom root element styleUTSJSONObject--
customClassCustom root element style classstring''-
fullWhether to leave a gap on both sides of the screenbooleanfalse-
titleTitle on the left of the headerstring''-
titleColorTitle colorstring''-
titleSizeTitle font size, in pxstring | number'15'-
subTitleSubtitle on the right of the headerstring''-
subTitleColorSubtitle colorstring''-
subTitleSizeSubtitle font size, in pxstring | number'13'-
borderWhether to show the outer borderbooleanfalse-
indexIdentifies which card was clickedCardIndex''-
boxShadowOuter shadow of the card, as a stringstring'none'-
marginSpacing between the card and the elements around it; a unit is requiredstring'15px'-
borderRadiusOverall border radius of the card, in pxstring | number'8'-
headStyleCustom style for the headerUTSJSONObject--
bodyStyleCustom style for the bodyUTSJSONObject--
footStyleCustom style for the footerUTSJSONObject--
headBorderBottomWhether to show the header's bottom borderbooleantrue-
footBorderTopWhether to show the footer's top borderbooleantrue-
showHeadWhether to show the headerbooleantrue-
showFootWhether to show the footerbooleantrue-
thumbThumbnail path shown on the left of the titlestring''-
thumbWidthThumbnail width and height, in pxstring | number'30'-
thumbCircleWhether the thumbnail is circularbooleanfalse-
paddingPadding of the header / body / footer, in pxstring | number'15'-

Events ​

EventDescriptionParamsVersion
clickFires when any part of the card is tappedindex: CardIndex-
head-clickFires when the card head is tappedindex: CardIndex-
body-clickFires when the card body is tappedindex: CardIndex-
foot-clickFires when the card foot is tappedindex: CardIndex-

Slots ​

SlotDescriptionVersion
headCustom header content; when provided it replaces the built-in header built from title / sub-title / thumb-
defaultCard body content-
bodyAdditional body content, rendered after the default slot-
footCustom footer content-

Notes ​

  1. Once a head slot is provided, the built-in header (built from title / sub-title / thumb) is no longer rendered; the two do not stack.
  2. The header and footer are toggled by show-head / show-foot, while the body always renders. When show-foot is true but no foot slot is passed, the footer is empty with zero padding.
  3. With full=true the component forces margin: 0 via inline style and makes the card fill its parent width, so the margin prop no longer applies.
  4. head-border-bottom / foot-border-top control the header's bottom border and the footer's top border respectively; both default to true.
  5. A long title is capped at 200px and truncated with an ellipsis; sub-title sits on the same line, aligned to the opposite end.
  6. Besides click, the source also emits head-click / body-click / foot-click when the header, body or footer is tapped (each callback is the index).