ProductCard
简介
ProductCard 组件用于展示产品信息,包括产品名称、图片、描述、App Store链接和产品官网链接。组件采用卡片式设计,支持悬停效果,并提供链接到产品相关页面的功能。
特性
- 多种尺寸 - 支持 xs、sm、md、lg、xl 五种预设尺寸
- 灵活布局 - 支持水平和垂直按钮布局
- 等高卡片 - 在网格布局中确保所有卡片高度一致
- 丰富链接 - 支持产品官网、App Store 和 GitHub 链接
- 自定义样式 - 支持自定义阴影、描述行数等样式
案例
点击查看
Vue 产品卡片
这是一个使用 Vue 版本的 ProductCard 组件的示例。
import { ProductCard } from '@coffic/cosy-ui';
<ProductCard
title="产品名称"
description="产品描述信息"
price="¥99.00"
image="https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=500"
href="/products/1"
/><template>
<ProductCard
name="Vue 产品卡片"
:image="productImage"
description="这是一个使用 Vue 版本的 ProductCard 组件的示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-basic",
});
</script>
Props
appStoreUrl
App Store 链接地址,用于跳转到 App Store 应用页面。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
import ProductCardAppStoreUrlSourceCode from "./ProductCardAppStoreUrl.astro?raw";
---
<ProductCard
name="App Store 产品"
image={getProductImage({ width: 300, height: 200, tag: 'appstore-product' })}
description="这是一个包含 App Store 链接的产品卡片示例。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example-app"
primaryButtonText="访问官网"
secondaryButtonText="App Store"
/>
<template>
<ProductCard
name="带 App Store 链接的产品卡片"
:image="productImage"
description="这是一个带有 App Store 链接的产品卡片示例。"
appStoreUrl="https://apps.apple.com/app/example"
:productUrl="productUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-appstore",
});
</script>
background
卡片背景色,支持基础颜色、透明度变体和渐变背景。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-default',
})}
description="使用默认背景色的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="主色背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-primary',
})}
description="使用主色背景的产品卡片。"
productUrl="https://example.com/product"
background="primary"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="渐变背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-gradient',
})}
description="使用日落渐变背景的产品卡片。"
productUrl="https://example.com/product"
background="gradient-sunset"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="透明度背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-opacity',
})}
description="使用主色透明度背景的产品卡片。"
productUrl="https://example.com/product"
background="primary-opacity"
/>
<template>
<ProductCard
name="带背景色的产品卡片"
:image="productImage"
description="这是一个带有自定义背景色的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
background="primary" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-background",
});
</script>
buttonLayout
按钮布局方向,支持水平(row)和垂直(column)两种布局方式。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="水平按钮布局"
image={getProductImage({ width: 300, height: 200, tag: 'button-row' })}
description="按钮水平排列,适合较宽的卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
buttonLayout="row"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="垂直按钮布局"
image={getProductImage({ width: 300, height: 200, tag: 'button-column' })}
description="按钮垂直排列,每个按钮占满一行。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
buttonLayout="column"
/>
class
自定义 CSS 类名,用于覆盖默认样式。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认产品卡片"
image={getProductImage({ width: 300, height: 200, tag: 'default-class' })}
description="使用默认样式的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义样式产品"
image={getProductImage({ width: 300, height: 200, tag: 'custom-class' })}
description="使用自定义类名添加额外样式的产品卡片。"
productUrl="https://example.com/product"
class="cosy:border-2 cosy:border-primary cosy:bg-primary/10"
/>
<template>
<ProductCard
name="自定义样式的产品卡片"
:image="productImage"
description="这是一个使用自定义样式的產品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
class="custom-product-card" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-class",
});
</script>
description
产品描述文本,支持多行显示。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="简短描述产品"
image={getProductImage({ width: 300, height: 200, tag: 'short-desc' })}
description="简短的产品描述。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="详细描述产品"
image={getProductImage({ width: 300, height: 200, tag: 'long-desc' })}
description="这是一个包含详细描述的产品卡片示例。产品描述可以包含更多信息,帮助用户更好地了解产品的特性和优势。这种详细的描述对于复杂产品或需要更多说明的产品特别有用。"
productUrl="https://example.com/product"
/>
<template>
<ProductCard
name="带描述的产品卡片"
:image="productImage"
description="这是一个带有详细描述的产品卡片示例。描述文本可以很长,组件会自动处理换行和截断。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-description",
});
</script>
descriptionLines
描述文本的最大显示行数,超出部分会被截断。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:grid cosy:grid-cols-2 cosy:gap-4">
<ProductCard
size="md"
name="默认行数限制"
image={getProductImage({ width: 300, height: 200, tag: 'product-default' })}
description="默认情况下,描述文本会根据卡片尺寸自动限制行数。例如中等尺寸(md)卡片默认显示3行文本。这段文本很长,但只会显示前几行,其余部分会被截断。"
productUrl="https://example.com/product3"
/>
<ProductCard
size="md"
descriptionLines={2}
name="自定义行数限制"
image={getProductImage({ width: 300, height: 200, tag: 'product-custom' })}
description="通过设置descriptionLines=2,可以将描述文本限制为最多显示2行。这段文本很长,但只会显示2行,其余部分会被截断。"
productUrl="https://example.com/product4"
/>
</div>
equalHeight
是否启用等高卡片,在网格布局中确保所有卡片高度一致。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:grid cosy:grid-cols-2 cosy:gap-4">
<ProductCard
equalHeight
size="md"
name="产品一"
image={getProductImage({ width: 300, height: 200, tag: 'product-equal1' })}
description="这是一段很短的产品描述。"
productUrl="https://example.com/product1"
/>
<ProductCard
equalHeight
size="md"
name="产品二"
image={getProductImage({ width: 300, height: 200, tag: 'product-equal2' })}
description="这是一段较长的产品描述,包含更多详细信息,可能会导致卡片高度增加。使用equalHeight属性可以确保所有卡片高度一致。"
productUrl="https://example.com/product2"
appStoreUrl="https://apps.apple.com/app/product2"
/>
</div>
githubButtonText
GitHub 按钮的显示文本。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'github-default',
})}
description="使用默认 GitHub 按钮文本的产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/repo"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({ width: 300, height: 200, tag: 'github-custom' })}
description="使用自定义 GitHub 按钮文本的产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/repo"
githubButtonText="查看源码"
/>
githubUrl
GitHub 仓库链接地址。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无 GitHub 产品"
image={getProductImage({ width: 300, height: 200, tag: 'no-github' })}
description="没有 GitHub 链接的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="开源产品"
image={getProductImage({ width: 300, height: 200, tag: 'with-github' })}
description="包含 GitHub 仓库链接的开源产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/awesome-project"
/>
<template>
<ProductCard
name="带 GitHub 链接的产品卡片"
:image="productImage"
description="这是一个带有 GitHub 链接的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
:githubUrl="githubUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const githubUrl = ref("https://github.com/example/project");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-github",
});
</script>
image
产品图片,支持多种图片源格式。
产品图片示例
点击查看
带图片的产品卡片
这是一个展示产品图片的产品卡片示例。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:space-y-4">
<div>
<h3 class="cosy:text-lg cosy:font-semibold cosy:mb-2">产品图片示例</h3>
<ProductCard
name="产品图片展示"
image={getProductImage({ width: 300, height: 200, tag: 'product-image' })}
description="展示产品图片的使用方式,支持多种图片源格式。"
productUrl="https://example.com/product"
/>
</div>
</div>
<template>
<ProductCard
name="带图片的产品卡片"
:image="productImage"
description="这是一个展示产品图片的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-image",
});
</script>
muted
是否使用柔和色样式(未激活状态),设置为 true 时卡片会呈现半透明效果并禁用交互。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="静音产品卡片"
image={getProductImage({ width: 300, height: 200, tag: 'product-muted' })}
description="这是一个使用了 muted 属性的产品卡片,看起来处于未激活状态。"
productUrl="https://example.com"
appStoreUrl="https://apps.apple.com/app/example"
muted
/>
name
产品名称,必填属性。
产品名称示例
点击查看
产品名称示例
这是一个展示产品名称的产品卡片示例。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:space-y-4">
<div>
<h3 class="cosy:text-lg cosy:font-semibold cosy:mb-2">产品名称示例</h3>
<ProductCard
name="产品名称展示"
image={getProductImage({ width: 300, height: 200, tag: 'product-name' })}
description="展示产品名称的使用方式,这是必填属性。"
productUrl="https://example.com/product"
/>
</div>
</div>
<template>
<ProductCard
name="产品名称示例"
:image="productImage"
description="这是一个展示产品名称的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-name",
});
</script>
primaryButtonText
主按钮(产品官网按钮)的显示文本。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'primary-default',
})}
description="使用默认主按钮文本的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'primary-custom',
})}
description="使用自定义主按钮文本的产品卡片。"
productUrl="https://example.com/product"
primaryButtonText="立即访问"
/>
productUrl
产品官网链接地址。
无链接产品
没有产品官网链接的卡片。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无链接产品"
image={getProductImage({ width: 300, height: 200, tag: 'no-url' })}
description="没有产品官网链接的卡片。"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="有链接产品"
image={getProductImage({ width: 300, height: 200, tag: 'with-url' })}
description="包含产品官网链接的卡片。"
productUrl="https://example.com/product"
/>
secondaryButtonText
次按钮(App Store 按钮)的显示文本。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'secondary-default',
})}
description="使用默认次按钮文本的产品卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'secondary-custom',
})}
description="使用自定义次按钮文本的产品卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
secondaryButtonText="下载应用"
/>
shadow
卡片阴影样式,提供 none、sm、md、lg、xl 五种样式选择。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="大阴影产品"
image={getProductImage({ width: 300, height: 200, tag: 'product-shadow-lg' })}
description="使用大阴影突出显示的产品。"
productUrl="https://example.com/product"
shadow="lg"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无阴影产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'product-shadow-none',
})}
description="无阴影的简洁风格。"
productUrl="https://example.com/product"
shadow="none"
/>
size
卡片尺寸,支持 xs、sm、md、lg、xl 五种预设尺寸。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="xs"
name="超小尺寸产品"
image={getProductImage({ width: 150, height: 100, tag: 'product-xs' })}
description="小巧精致的产品卡片,节省空间。"
productUrl="https://example.com/xs"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="sm"
name="小尺寸产品"
image={getProductImage({ width: 150, height: 100, tag: 'product-sm' })}
description="紧凑型产品卡片,适合在列表中展示。"
productUrl="https://example.com/sm"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="md"
name="中等尺寸产品"
image={getProductImage({ width: 300, height: 200, tag: 'product-md' })}
description="标准产品卡片,平衡信息展示和空间占用。"
productUrl="https://example.com/md"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="lg"
name="大尺寸产品"
image={getProductImage({ width: 380, height: 253, tag: 'product-lg' })}
description="大尺寸产品卡片,提供更多细节和视觉吸引力,适合突出展示重要产品。"
productUrl="https://example.com/lg"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="xl"
name="超大尺寸产品"
image={getProductImage({ width: 480, height: 320, tag: 'product-xl' })}
description="超大尺寸产品卡片,提供最佳视觉体验和完整信息展示,适合特色产品或首页展示。"
productUrl="https://example.com/xl"
appStoreUrl="https://apps.apple.com/app/example-xl"
/>
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<ProductCard
name="超小尺寸 (xs)"
:image="productImageXs"
description="超小尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="xs" />
<ProductCard
name="小尺寸 (sm)"
:image="productImageSm"
description="小尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="sm" />
<ProductCard
name="中等尺寸 (md)"
:image="productImageMd"
description="中等尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="md" />
<ProductCard
name="大尺寸 (lg)"
:image="productImageLg"
description="大尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="lg" />
<ProductCard
name="超大尺寸 (xl)"
:image="productImageXl"
description="超大尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="xl" />
</div>
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImageXs = getProductImage({
width: 200,
height: 133,
tag: "product-xs",
});
const productImageSm = getProductImage({
width: 250,
height: 167,
tag: "product-sm",
});
const productImageMd = getProductImage({
width: 300,
height: 200,
tag: "product-md",
});
const productImageLg = getProductImage({
width: 400,
height: 267,
tag: "product-lg",
});
const productImageXl = getProductImage({
width: 500,
height: 333,
tag: "product-xl",
});
</script>
