PricingTable 组件提供了一种响应式且可定制的方式来以表格形式显示定价方案,在桌面端自动切换为横向表格布局以便于比较,在移动端则切换为纵向卡片布局以提高可读性。
使用 tiers prop 作为对象数组来定义您的定价方案。每个层级对象支持以下属性:
id: string - 层级的唯一标识符(必需)title?: string - 定价方案的名称description?: string - 方案的简短描述price?: string - 方案的当前价格(例如,“$99”,“€99”,“免费”)discount?: string - 折扣价格,将以删除线显示 price(例如,“$79”,“€79”)billingCycle?: string - 显示在价格旁边的单位价格周期(例如,“/月”,“/席位/月”)billingPeriod?: string - 显示在计费周期上方的额外计费上下文(例如,“按月计费”)badge?: string | BadgeProps - 在标题旁边显示徽章 { color: 'primary', variant: 'subtle' }button?: ButtonProps - 配置 CTA 按钮 { size: 'lg', block: true }highlight?: boolean - 是否将此层级作为推荐选项进行视觉强调<script setup lang="ts">
const tiers = ref([
{
id: 'solo',
title: 'Solo',
description: 'For indie hackers.',
price: '$249',
billingCycle: '/month',
billingPeriod: 'billed annually',
badge: 'Most popular',
button: {
label: 'Buy now',
variant: 'subtle'
}
},
{
id: 'team',
title: 'Team',
description: 'For growing teams.',
price: '$499',
billingCycle: '/month',
billingPeriod: 'billed annually',
button: {
label: 'Buy now'
},
highlight: true
},
{
id: 'enterprise',
title: 'Enterprise',
description: 'For large organizations.',
price: 'Custom',
button: {
label: 'Contact sales',
color: 'neutral'
}
}
])
</script>
<template>
<UPricingTable :tiers="tiers" />
</template>
使用 sections prop 将功能组织成逻辑组。每个部分代表您想要在不同定价层级之间进行比较的功能类别。
title: string - 功能部分的标题features: PricingTableSectionFeature[] - 一个功能数组,其中包含它们在每个层级中的可用性title 和一个 tiers 对象,用于将层级 ID 映射到值true/false)将显示为复选标记 (✓) 或减号图标 (-)<script setup lang="ts">
const tiers = ref([
{
id: 'solo',
title: 'Solo',
price: '$249',
description: 'For indie hackers.',
billingCycle: '/month',
button: {
label: 'Buy now',
variant: 'subtle'
}
},
{
id: 'team',
title: 'Team',
price: '$499',
description: 'For growing teams.',
billingCycle: '/month',
button: {
label: 'Buy now'
}
},
{
id: 'enterprise',
title: 'Enterprise',
price: 'Custom',
description: 'For large organizations.',
button: {
label: 'Contact sales',
color: 'neutral'
}
}
])
const sections = ref([
{
title: 'Features',
features: [
{
title: 'Number of developers',
tiers: {
solo: '1',
team: '5',
enterprise: 'Unlimited'
}
},
{
title: 'Projects',
tiers: {
solo: true,
team: true,
enterprise: true
}
}
]
},
{
title: 'Security',
features: [
{
title: 'SSO',
tiers: {
solo: false,
team: true,
enterprise: true
}
}
]
}
])
</script>
<template>
<UPricingTable :tiers="tiers" :sections="sections" />
</template>
PricingTable 组件提供了强大的插槽自定义选项,以根据您的需求定制内容的显示。您可以使用通用插槽自定义单个元素,或使用其 ID 定位特定项目。
<script setup lang="ts">
const tiers = [
{
id: 'solo',
title: 'Solo',
price: '$249',
description: 'For indie hackers.',
billingCycle: '/month',
button: { label: 'Buy now', variant: 'subtle' as const }
},
{
id: 'team',
title: 'Team',
price: '$499',
description: 'For growing teams.',
billingCycle: '/month',
button: { label: 'Buy now' },
highlight: true
},
{
id: 'enterprise',
title: 'Enterprise',
price: 'Custom',
description: 'For large organizations.',
button: { label: 'Contact sales', color: 'neutral' as const }
}
]
const sections = [
{
id: 'features',
title: 'Features',
features: [
{
id: 'developers',
title: 'Number of developers',
tiers: { solo: '1', team: '5', enterprise: 'Unlimited' }
},
{
id: 'projects',
title: 'Projects',
tiers: { solo: true, team: true, enterprise: true }
}
]
},
{
id: 'security',
title: 'Security',
features: [
{
title: 'SSO',
tiers: { solo: false, team: true, enterprise: true }
}
]
}
]
</script>
<template>
<UPricingTable :tiers="tiers" :sections="sections">
<!-- Customize specific tier title -->
<template #team-title="{ tier }">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-crown" class="size-4 text-amber-500" />
{{ tier.title }}
</div>
</template>
<!-- Customize specific section title -->
<template #section-security-title="{ section }">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-shield-check" class="size-4 text-green-500" />
<span class="font-semibold text-green-700">{{ section.title }}</span>
</div>
</template>
<!-- Customize specific feature value -->
<template #feature-developers-value="{ feature, tier }">
<template v-if="feature.tiers?.[tier.id]">
<UBadge :label="String(feature.tiers[tier.id])" color="primary" variant="soft" />
</template>
<UIcon v-else name="i-lucide-x" class="size-4 text-muted" />
</template>
</UPricingTable>
</template>
该组件支持各种插槽类型,以实现最大的自定义灵活性
| 插槽类型 | 模式 | 描述 | 示例 |
|---|---|---|---|
| 层级插槽 | #{层级-id}-{元素} | 定位特定层级 | #team-title, #solo-price |
| 部分插槽 | #section-{id|格式化标题}-title | 定位特定部分 | #section-features-title |
| 功能插槽 | #feature-{id|格式化标题}-{标题|值} | 定位特定功能 | #feature-developers-title |
| 通用插槽 | #tier-title, #section-title 等。 | 适用于所有项目 | #feature-value |
id,则插槽名称将根据标题自动生成(例如,“Premium Features!” 变为 #section-premium-features-title)。| 属性 | 默认值 | 类型 |
|---|---|---|
as |
|
此组件应渲染为的元素或组件。 |
tiers |
要在表格中显示的定价层级。每个层级代表一个定价方案,具有自己的标题、描述、价格和功能。
| |
sections |
要在表格中显示的功能部分。每个部分包含一个标题和功能列表,以及它们在每个层级中的可用性。 | |
caption |
显示在表格上方的标题。 | |
ui |
|
| 插槽 | 类型 |
|---|---|
caption |
|
tier | |
tier-title | |
tier-description | |
tier-badge | |
tier-button | |
tier-billing | |
tier-discount | |
tier-price |
|
section-title |
|
feature-title |
|
feature-value |
|
export default defineAppConfig({
ui: {
pricingTable: {
slots: {
root: 'w-full relative',
table: 'w-full table-fixed border-separate border-spacing-x-0 hidden md:table',
list: 'md:hidden flex flex-col gap-6 w-full',
item: 'p-6 flex flex-col border border-default rounded-lg',
caption: 'sr-only',
thead: '',
tbody: '',
tr: '',
th: 'py-4 font-normal text-left border-b border-default',
td: 'px-6 py-4 text-center border-b border-default',
tier: 'p-6 text-left font-normal',
tierTitleWrapper: 'flex items-center gap-3',
tierTitle: 'text-lg font-semibold text-highlighted',
tierDescription: 'text-sm font-normal text-muted mt-1',
tierBadge: 'truncate',
tierPriceWrapper: 'flex items-center gap-1 mt-4',
tierPrice: 'text-highlighted text-3xl sm:text-4xl font-semibold',
tierDiscount: 'text-muted line-through text-xl sm:text-2xl',
tierBilling: 'flex flex-col justify-between min-w-0',
tierBillingPeriod: 'text-toned truncate text-xs font-medium',
tierBillingCycle: 'text-muted truncate text-xs font-medium',
tierButton: 'mt-6',
tierFeatureIcon: 'size-5 shrink-0',
section: 'mt-6 flex flex-col gap-2',
sectionTitle: 'font-semibold text-sm text-highlighted',
feature: 'flex items-center justify-between gap-1',
featureTitle: 'text-sm text-default',
featureValue: 'text-sm text-muted flex justify-center min-w-5'
},
variants: {
section: {
true: {
tr: '*:pt-8'
}
},
active: {
true: {
tierFeatureIcon: 'text-primary'
}
},
highlight: {
true: {
tier: 'bg-elevated/50 border-x border-t border-default rounded-t-lg',
td: 'bg-elevated/50 border-x border-default',
item: 'bg-elevated/50'
}
}
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
pricingTable: {
slots: {
root: 'w-full relative',
table: 'w-full table-fixed border-separate border-spacing-x-0 hidden md:table',
list: 'md:hidden flex flex-col gap-6 w-full',
item: 'p-6 flex flex-col border border-default rounded-lg',
caption: 'sr-only',
thead: '',
tbody: '',
tr: '',
th: 'py-4 font-normal text-left border-b border-default',
td: 'px-6 py-4 text-center border-b border-default',
tier: 'p-6 text-left font-normal',
tierTitleWrapper: 'flex items-center gap-3',
tierTitle: 'text-lg font-semibold text-highlighted',
tierDescription: 'text-sm font-normal text-muted mt-1',
tierBadge: 'truncate',
tierPriceWrapper: 'flex items-center gap-1 mt-4',
tierPrice: 'text-highlighted text-3xl sm:text-4xl font-semibold',
tierDiscount: 'text-muted line-through text-xl sm:text-2xl',
tierBilling: 'flex flex-col justify-between min-w-0',
tierBillingPeriod: 'text-toned truncate text-xs font-medium',
tierBillingCycle: 'text-muted truncate text-xs font-medium',
tierButton: 'mt-6',
tierFeatureIcon: 'size-5 shrink-0',
section: 'mt-6 flex flex-col gap-2',
sectionTitle: 'font-semibold text-sm text-highlighted',
feature: 'flex items-center justify-between gap-1',
featureTitle: 'text-sm text-default',
featureValue: 'text-sm text-muted flex justify-center min-w-5'
},
variants: {
section: {
true: {
tr: '*:pt-8'
}
},
active: {
true: {
tierFeatureIcon: 'text-primary'
}
},
highlight: {
true: {
tier: 'bg-elevated/50 border-x border-t border-default rounded-t-lg',
td: 'bg-elevated/50 border-x border-default',
item: 'bg-elevated/50'
}
}
}
}
}
})
]
})
5cb65— 特性:导入 @nuxt/ui-pro 组件