PricingTable 价格表

用于展示不同订阅方案/套餐的对比价格表,桌面端为表格布局、移动端自动切换为卡片列表,支持高亮推荐方案与自定义插槽。

响应式价格方案表格组件,以分层级的价格方案展示功能对比。桌面端自动切换为横向表格布局便于对比,移动端切换为纵向卡片布局提升可读性。

何时使用

  • SaaS 产品定价页、订阅方案对比。
  • 需要以表格形式横向对比多个方案的功能差异时。
  • 适合 2~4 个价格层级的场景。

导入

import { PricingTable } from "@reglow/reui";

代码演示

基础用法

通过 tiers 定义价格层级,通过 sections 定义功能区段。功能值支持 boolean(显示 ✓ / -)、string 和 number。

<script setup lang="ts">
import type { PricingTableTier, PricingTableSection } from "@reglow/reui";
import { PricingTable } from "@reglow/reui";

const tiers: PricingTableTier[] = [
  {
    id: "solo",
    title: "Solo",
    description: "适合独立开发者。",
    price: "¥249",
    billingCycle: "/月",
    billingPeriod: "按年计费",
    badge: "最受欢迎",
    button: { label: "立即购买", variant: "outline" },
  },
  {
    id: "team",
    title: "Team",
    description: "适合成长型团队。",
    price: "¥499",
    billingCycle: "/月",
    billingPeriod: "按年计费",
    button: { label: "立即购买" },
    highlight: true,
  },
  {
    id: "enterprise",
    title: "Enterprise",
    description: "适合大型组织。",
    price: "定制",
    button: { label: "联系销售", variant: "secondary" },
  },
];

const sections: PricingTableSection[] = [
  {
    title: "核心功能",
    features: [
      { title: "开发者数量", tiers: { solo: "1", team: "5", enterprise: "不限" } },
      { title: "项目数量", tiers: { solo: true, team: true, enterprise: true } },
      { title: "GitHub 仓库访问", tiers: { solo: true, team: true, enterprise: true } },
      { title: "更新频率", tiers: { solo: "补丁和小版本", team: "全部更新", enterprise: "全部更新" } },
    ],
  },
  {
    title: "安全",
    features: [
      { title: "SSO 单点登录", tiers: { solo: false, team: true, enterprise: true } },
      { title: "审计日志", tiers: { solo: false, team: true, enterprise: true } },
      { title: "自定义安全审查", tiers: { solo: false, team: false, enterprise: true } },
    ],
  },
];
</script>

<template>
  <PricingTable :tiers="tiers" :sections="sections" />
</template>

仅展示层级(无功能对比)

不传 sections 时,仅展示各层级的价格信息和 CTA 按钮。

<script setup lang="ts">
import type { PricingTableTier } from "@reglow/reui";
import { PricingTable } from "@reglow/reui";

const tiers: PricingTableTier[] = [
  {
    id: "free",
    title: "Free",
    price: "免费",
    description: "入门体验。",
    button: { label: "开始使用", variant: "outline" },
  },
  {
    id: "pro",
    title: "Pro",
    price: "¥99",
    billingCycle: "/月",
    description: "专业功能。",
    button: { label: "立即升级" },
    highlight: true,
  },
];
</script>

<template>
  <PricingTable :tiers="tiers" />
</template>

折扣价

通过 discount 设置折扣价,会以删除线显示在原价旁边。

<script setup lang="ts">
import type { PricingTableTier } from "@reglow/reui";
import { PricingTable } from "@reglow/reui";

const tiers: PricingTableTier[] = [
  {
    id: "pro",
    title: "Pro",
    price: "¥99",
    discount: "¥199",
    billingCycle: "/月",
    button: { label: "立即购买" },
    highlight: true,
  },
];
</script>

<template>
  <PricingTable :tiers="tiers" />
</template>

使用插槽自定义

组件支持通用插槽和按 ID 定位的特定插槽。特定插槽优先级高于通用插槽。

<script setup lang="ts">
import type { PricingTableTier, PricingTableSection } from "@reglow/reui";
import { PricingTable } from "@reglow/reui";
import { Crown, ShieldCheck } from "lucide-vue-next";

const tiers: PricingTableTier[] = [
  { id: "solo", title: "Solo", price: "¥249", button: { label: "购买" } },
  { id: "team", title: "Team", price: "¥499", button: { label: "购买" }, highlight: true },
];
const sections: PricingTableSection[] = [
  { id: "features", title: "功能", features: [
    { title: "开发者", tiers: { solo: "1", team: "5" } },
  ]},
  { id: "security", title: "安全", features: [
    { title: "SSO", tiers: { solo: false, team: true } },
  ]},
];
</script>

<template>
  <PricingTable :tiers="tiers" :sections="sections">
    <!-- 特定层级标题 -->
    <template #team-title="{ tier }">
      <span class="flex items-center gap-1.5">
        <Crown class="size-4 text-amber-500" />
        {{ tier.title }}
      </span>
    </template>

    <!-- 特定区段标题 -->
    <template #section-security-title="{ section }">
      <span class="flex items-center gap-1.5 text-green-600 font-semibold">
        <ShieldCheck class="size-4" />
        {{ section.title }}
      </span>
    </template>

    <!-- 特定功能值 -->
    <template #feature-开发者-value="{ value }">
      <span class="font-bold text-primary">{{ value }}</span>
    </template>
  </PricingTable>
</template>

API

Props

参数说明类型默认值
tiers价格层级列表(必填)PricingTableTier[]-
sections功能区段列表PricingTableSection[]-
caption表格标题(无障碍,视觉隐藏)string-
class附加类名string-

PricingTableTier

属性说明类型
id唯一标识符(必填)string
title方案名称string
description方案描述string
price当前价格string
discount折扣价(删除线展示)string
billingCycle价格周期(如 "/月")string
billingPeriod计费说明(如 "按年计费")string
badge标题旁的徽章文字string
buttonCTA 按钮配置{ label?: string; variant?: ButtonVariants["variant"]; size?: ButtonVariants["size"] }
highlight是否高亮此层级boolean

PricingTableSection

属性说明类型
title区段标题string
id区段标识符(用于插槽定位,可选)string
features功能列表PricingTableSectionFeature[]

PricingTableSectionFeature

属性说明类型
title功能标题string
tiers各层级对应值。true 显示 ✓,false 显示 -,string/number 显示文本Record<string, boolean | string | number>

Slots

组件支持通用插槽和特定插槽,特定插槽优先级更高。

插槽类型模式说明示例
层级插槽#{tier-id}-{element}定位特定层级#team-title、#solo-price
区段插槽#section-{id|formatted-title}-title定位特定区段#section-security-title
功能插槽#feature-{formatted-title}-value定位特定功能值#feature-开发者-value
通用插槽#tier-title 等应用到所有项#feature-value

通用插槽列表:

名称说明插槽参数
tier-title层级标题{ tier }
tier-description层级描述{ tier }
tier-price层级价格{ tier }
tier-billing计费信息{ tier }
tier-buttonCTA 按钮{ tier }
section-title区段标题{ section }
feature-title功能标题{ feature }
feature-value功能值{ feature, tier, value }

当区段或功能没有显式 id 时,插槽名由标题自动生成(转为 kebab-case)。

响应式行为

  • 桌面端(md 及以上):渲染为 HTML <table>,各层级为列,功能为行,便于横向对比。
  • 移动端(md 以下):渲染为卡片列表,每个卡片为一个层级,功能在卡片内纵向排列。