Card
组合标题、正文、操作和页脚形成卡片,也可加入选择状态。
适用场景
- 当界面需要以下行为时使用 Card:组合标题、正文、操作和页脚形成卡片,也可加入选择状态。
安装
选择安装方式,用法示例将同步更新导入路径。
$ bunx --bun shadcn-vue@2.8.2 add https://orvui.efu.me/r/card.json https://orvui.efu.me/r/button.json https://orvui.efu.me/r/checkbox.json https://orvui.efu.me/r/switch.json
首次使用时,将安装的 src/components/orvui/styles.css 导入项目样式入口。
示例
预览
Signed contract
The final PDF with every signature and the audit trail.
Invoice
Itemised billing for the period, ready for accounting.
Notifications
Choose what reaches your inbox.
Mentions and replies
Weekly digest
Review order
Check the details before you confirm.
- Plan
- Team, yearly
- Seats
- 12
- Billing email
- billing@acme.co
Studio, Lisbon
Desks for 12 people, booked for the March offsite.
€1,840 · 3 days
packages/vue/src/motion/card/demo.vue
<script setup lang="ts">
import { reactive, ref, useId } from "vue";
import { Button } from "@/components/orvui/motion/button";
import { Checkbox } from "@/components/orvui/motion/checkbox";
import { Switch } from "@/components/orvui/motion/switch";
import { CARD_TARGET_CLASS, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/orvui/motion/card";
const instanceId = useId();
const documents = ref([
{ id: "agreement", title: "Signed contract", description: "The final PDF with every signature and the audit trail.", checked: true },
{ id: "billing", title: "Invoice", description: "Itemised billing for the period, ready for accounting.", checked: false },
]);
const preferences = reactive({ notifications: true, digest: false });
const rows = Object.entries({ Plan: "Team, yearly", Seats: "12", "Billing email": "billing@acme.co" });
</script>
<template>
<div class="grid w-full max-w-3xl items-start gap-4 md:grid-cols-2">
<div class="flex flex-col gap-3">
<Card v-for="document in documents" :key="document.id" size="compact" interactive :selected="document.checked">
<CardHeader><CardTitle>{{ document.title }}</CardTitle><CardDescription :id="`${instanceId}-${document.id}`">{{ document.description }}</CardDescription>
<CardAction><Checkbox v-model="document.checked" :aria-label="document.title" :aria-describedby="`${instanceId}-${document.id}`" :class="CARD_TARGET_CLASS" /></CardAction>
</CardHeader>
</Card>
<Card variant="muted" size="compact">
<CardHeader><CardTitle as="h3">Notifications</CardTitle><CardDescription>Choose what reaches your inbox.</CardDescription></CardHeader>
<CardContent class="flex flex-col gap-3">
<div class="flex items-center justify-between gap-4"><span>Mentions and replies</span><Switch v-model="preferences.notifications" aria-label="Mentions and replies" /></div>
<div class="flex items-center justify-between gap-4"><span>Weekly digest</span><Switch v-model="preferences.digest" aria-label="Weekly digest" /></div>
</CardContent>
</Card>
</div>
<div class="flex flex-col gap-4">
<Card>
<CardHeader><CardTitle as="h3">Review order</CardTitle><CardDescription>Check the details before you confirm.</CardDescription><CardAction><Button variant="ghost" size="sm">Edit</Button></CardAction></CardHeader>
<CardContent><dl class="divide-y divide-border"><div v-for="[label, value] in rows" :key="label" class="flex items-center justify-between gap-4 py-2.5 first:pt-0 last:pb-0"><dt class="text-muted-foreground">{{ label }}</dt><dd class="font-medium text-foreground">{{ value }}</dd></div></dl></CardContent>
<CardFooter class="justify-end"><Button variant="secondary" size="sm">Back</Button><Button size="sm">Confirm order</Button></CardFooter>
</Card>
<Card class="overflow-hidden pt-0">
<img src="https://images.unsplash.com/photo-1497366754035-f200968a6e72?auto=format&fit=crop&w=720&q=80" alt="Bright open-plan studio with long desks and plants" :width="720" :height="405" loading="lazy" class="aspect-video w-full object-cover" />
<CardHeader><CardTitle as="h3">Studio, Lisbon</CardTitle><CardDescription>Desks for 12 people, booked for the March offsite.</CardDescription></CardHeader>
<CardFooter class="justify-between"><span class="text-sm text-muted-foreground"><span class="font-medium text-foreground">€1,840</span> · 3 days</span><Button variant="secondary" size="sm">View booking</Button></CardFooter>
</Card>
</div>
</div>
</template>
packages/vue/src/motion/card/src/Card.vue
状态与事件
此示例组合没有声明成对的受控属性与 update 事件。使用已列出的属性、原生事件和插槽组合内容;不要为它添加未公开的 v-model。
API 参考
Card
variant?"outlined" | "muted""outlined"size?"default" | "compact""default"interactive?booleanfalseselected?booleanfalse插槽
default() => VNodeChild#defaultCardAction
插槽
default() => any#defaultCardContent
插槽
default() => any#defaultCardDescription
插槽
default() => any#defaultCardFooter
插槽
default() => any#defaultCardHeader
插槽
default() => any#defaultCardTitle
as?"div" | "h2" | "h3" | "h4""div"插槽
default() => VNodeChild#default无障碍
为交互控件提供明确的无障碍名称。保留文档中的键盘路径、可见焦点与减少动态效果状态;自定义插槽应继续保留所替代部件的语义。
常见问题
- 如何配置 Card?
- 通过 variant、size、interactive、selected 配置 Card;API 表列出其类型与默认值。
- 如何连接到应用状态?
- 通过default 插槽提供内容,应用副作用由调用方管理。
- 可以在服务端渲染吗?
- 可以在 Vue SSR 应用中正常渲染。服务端与客户端的初始 props 应保持一致;浏览器测量与交互资源在挂载后启动。
更新于
来源与许可 ↗MIT · 0.1.1