定价方案

GitHub
一个可自定义的定价计划,用于在定价页面中显示。

用法

PricingPlan 组件提供了一种灵活的方式来展示包含可自定义内容(如标题、描述、价格、功能等)的定价方案。

个人版
最受欢迎
面向初创公司和独立开发者。
$249
$199
 /月
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
使用 PricingPlans 组件以响应式网格布局显示多个定价方案。

标题

使用 title 属性来设置 PricingPlan 的标题。

个人版
<template>
  <UPricingPlan title="Solo" class="w-96" />
</template>

描述

使用 description 属性来设置 PricingPlan 的描述。

个人版
面向初创公司和独立开发者。
<template>
  <UPricingPlan title="Solo" description="For bootstrappers and indie hackers." />
</template>

Badge

使用 badge 属性在 PricingPlan 标题旁边显示一个 Badge

个人版
最受欢迎
面向初创公司和独立开发者。
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    badge="Most popular"
  />
</template>

您可以传递 Badge 组件的任何属性来对其进行自定义。

个人版
最受欢迎
面向初创公司和独立开发者。
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    :badge="{
      label: 'Most popular',
      color: 'neutral',
      variant: 'solid'
    }"
  />
</template>

价格

使用 price 属性来设置 PricingPlan 的价格。

个人版
面向初创公司和独立开发者。
$249
<template>
  <UPricingPlan title="Solo" description="For bootstrappers and indie hackers." price="$249" />
</template>

折扣

使用 discount 属性来设置一个折扣价格,该价格将与原价(将显示删除线)一起显示。

个人版
面向初创公司和独立开发者。
$249
$199
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    discount="$199"
  />
</template>

账单

使用 billing-cycle 和/或 billing-period 属性来显示 PricingPlan 的账单信息。

个人版
面向初创公司和独立开发者。
$9
每年账单/月
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$9"
    billing-cycle="/month"
    billing-period="billed annually"
  />
</template>

功能

使用 features 属性作为字符串数组,以在 PricingPlan 上显示功能列表。

个人版
面向初创公司和独立开发者。
$249
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Unlimited patch & minor updates',
      'Lifetime access'
    ]"
  />
</template>
您可以在 app.config.ts 文件中,通过 ui.icons.success 键全局自定义此图标。
您可以在 vite.config.ts 文件中,通过 ui.icons.success 键全局自定义此图标。

您还可以传入一个包含以下属性的对象数组

  • title: string
  • icon?: string
个人版
面向初创公司和独立开发者。
$249
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
<script setup lang="ts">
const features = ref([
  {
    title: 'One developer',
    icon: 'i-lucide-user'
  },
  {
    title: 'Unlimited projects',
    icon: 'i-lucide-infinity'
  },
  {
    title: 'Access to GitHub repository',
    icon: 'i-lucide-github'
  },
  {
    title: 'Unlimited patch & minor updates',
    icon: 'i-lucide-refresh-cw'
  },
  {
    title: 'Lifetime access',
    icon: 'i-lucide-clock'
  }
])
</script>

<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="features"
  />
</template>

Button

使用 button 属性,并附带 Button 组件的任何属性,以在 PricingPlan 底部显示按钮。

个人版
面向初创公司和独立开发者。
$249
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Unlimited patch & minor updates',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
  />
</template>
使用 onClick 字段添加一个点击事件处理程序,以触发计划购买。

变体

使用 variant 属性来更改 PricingPlan 的变体。

个人版
面向初创公司和独立开发者。
$249
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Unlimited patch & minor updates',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
    variant="subtle"
  />
</template>

Orientation

使用 orientation 属性来更改 PricingPlan 的方向。默认为 vertical

个人版
面向初创公司和独立开发者。
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 终身访问
$249
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
    orientation="horizontal"
    variant="outline"
  />
</template>

标语

使用 tagline 属性在价格上方显示标语文本。

个人版
面向初创公司和独立开发者。
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 终身访问
一次性支付,永久拥有
$249
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
    orientation="horizontal"
    tagline="Pay once, own it forever"
  />
</template>

条款

使用 terms 属性在价格下方显示条款。

个人版
面向初创公司和独立开发者。
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 终身访问
一次性支付,永久拥有
$249
提供发票和收据。
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
    orientation="horizontal"
    tagline="Pay once, own it forever"
    terms="Invoices and receipts available."
  />
</template>

高亮显示

使用 highlight 属性为 PricingPlan 显示一个突出的边框。

个人版
面向初创公司和独立开发者。
$249
  • 一名开发者
  • 无限项目
  • 访问 GitHub 仓库
  • 无限次补丁和次要更新
  • 终身访问
<template>
  <UPricingPlan
    title="Solo"
    description="For bootstrappers and indie hackers."
    price="$249"
    :features="[
      'One developer',
      'Unlimited projects',
      'Access to GitHub repository',
      'Unlimited patch & minor updates',
      'Lifetime access'
    ]"
    :button="{
      label: 'Buy now'
    }"
    highlight
  />
</template>

缩放

使用 scale 属性使一个 PricingPlan 比其他计划更大。

查看 PricingPlans 的 scale 示例,了解其工作原理,因为它很难单独演示。

API

属性

属性默认值类型
as

'div'

any

此组件应渲染为的元素或组件。

title

string

description

string

徽章

string | BadgeProps

在标题旁边显示一个徽章。可以是字符串或对象。 { color: 'primary', variant: 'subtle' }

billingCycle

string

显示在价格旁边的单价周期。通常用于显示重复计费间隔。

billingPeriod

string

显示在计费周期上方的额外计费上下文。通常用于显示实际的计费频率。

price

string

方案的当前价格。与 discount 一起使用时,这成为原始价格。

discount

string

方案的折扣价格。如果提供,price 属性将以删除线显示。

features

string[] | PricingPlanFeature[]

在价格下方显示功能列表。可以是字符串数组或对象数组。

button

ButtonProps

在底部显示一个购买按钮。 { size: 'lg', block: true } 使用 onClick 字段添加一个点击处理程序。

tagline

string

显示一个标语,突出定价的价值主张。

terms

string

在底部显示条款。

orientation

'vertical'

"vertical" | "horizontal"

定价方案的方向。

variant

'outline'

"soft" | "solid" | "outline" | "subtle"

高亮

boolean

在定价方案周围显示一个环以突出显示它。

scale

boolean

放大方案,使其更突出。

ui

{ root?: ClassNameValue; header?: ClassNameValue; body?: ClassNameValue; footer?: ClassNameValue; titleWrapper?: ClassNameValue; title?: ClassNameValue; description?: ClassNameValue; priceWrapper?: ClassNameValue; price?: ClassNameValue; discount?: ClassNameValue; billing?: ClassNameValue; billingPeriod?: ClassNameValue; billingCycle?: ClassNameValue; features?: ClassNameValue; feature?: ClassNameValue; featureIcon?: ClassNameValue; featureTitle?: ClassNameValue; badge?: ClassNameValue; button?: ClassNameValue; tagline?: ClassNameValue; terms?: ClassNameValue; }

插槽

插槽类型
徽章

{}

title

{}

description

{}

price

{}

discount

{}

billing

{}

features

{}

button

{}

页头

{}

主体

{}

页脚

{}

tagline

{}

terms

{}

主题

app.config.ts
export default defineAppConfig({
  ui: {
    pricingPlan: {
      slots: {
        root: 'relative grid rounded-lg p-6 lg:p-8 xl:p-10 gap-6',
        header: '',
        body: 'flex flex-col min-w-0',
        footer: 'flex flex-col gap-6 items-center',
        titleWrapper: 'flex items-center gap-3',
        title: 'text-highlighted text-2xl sm:text-3xl text-pretty font-semibold',
        description: 'text-muted text-base text-pretty mt-2',
        priceWrapper: 'flex items-center gap-1',
        price: 'text-highlighted text-3xl sm:text-4xl font-semibold',
        discount: 'text-muted line-through text-xl sm:text-2xl',
        billing: 'flex flex-col justify-between min-w-0',
        billingPeriod: 'text-toned truncate text-xs font-medium',
        billingCycle: 'text-muted truncate text-xs font-medium',
        features: 'flex flex-col gap-3 flex-1 mt-6 grow-0',
        feature: 'flex items-center gap-2 min-w-0',
        featureIcon: 'size-5 shrink-0 text-primary',
        featureTitle: 'text-muted text-sm truncate',
        badge: '',
        button: '',
        tagline: 'text-base font-semibold text-default',
        terms: 'text-xs/5 text-muted text-center text-balance'
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'grid-cols-1 lg:grid-cols-3 justify-between divide-y lg:divide-y-0 lg:divide-x divide-default',
            body: 'lg:col-span-2 pb-6 lg:pb-0 lg:pr-6 justify-center',
            footer: 'lg:justify-center lg:items-center lg:p-6 lg:max-w-xs lg:w-full lg:mx-auto',
            features: 'lg:grid lg:grid-cols-2 lg:mt-12'
          },
          vertical: {
            footer: 'justify-end',
            priceWrapper: 'mt-6'
          }
        },
        variant: {
          solid: {
            root: 'bg-inverted',
            title: 'text-inverted',
            description: 'text-dimmed',
            price: 'text-inverted',
            discount: 'text-dimmed',
            billingCycle: 'text-dimmed',
            billingPeriod: 'text-dimmed',
            featureTitle: 'text-dimmed'
          },
          outline: {
            root: 'bg-default ring ring-default'
          },
          soft: {
            root: 'bg-elevated/50'
          },
          subtle: {
            root: 'bg-elevated/50 ring ring-default'
          }
        },
        highlight: {
          true: {
            root: 'ring-2 ring-inset ring-primary'
          }
        },
        scale: {
          true: {
            root: 'lg:scale-[1.1] lg:z-[1]'
          }
        }
      },
      compoundVariants: [
        {
          orientation: 'horizontal',
          variant: 'soft',
          class: {
            root: 'divide-accented'
          }
        },
        {
          orientation: 'horizontal',
          variant: 'subtle',
          class: {
            root: 'divide-accented'
          }
        }
      ],
      defaultVariants: {
        variant: 'outline'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        pricingPlan: {
          slots: {
            root: 'relative grid rounded-lg p-6 lg:p-8 xl:p-10 gap-6',
            header: '',
            body: 'flex flex-col min-w-0',
            footer: 'flex flex-col gap-6 items-center',
            titleWrapper: 'flex items-center gap-3',
            title: 'text-highlighted text-2xl sm:text-3xl text-pretty font-semibold',
            description: 'text-muted text-base text-pretty mt-2',
            priceWrapper: 'flex items-center gap-1',
            price: 'text-highlighted text-3xl sm:text-4xl font-semibold',
            discount: 'text-muted line-through text-xl sm:text-2xl',
            billing: 'flex flex-col justify-between min-w-0',
            billingPeriod: 'text-toned truncate text-xs font-medium',
            billingCycle: 'text-muted truncate text-xs font-medium',
            features: 'flex flex-col gap-3 flex-1 mt-6 grow-0',
            feature: 'flex items-center gap-2 min-w-0',
            featureIcon: 'size-5 shrink-0 text-primary',
            featureTitle: 'text-muted text-sm truncate',
            badge: '',
            button: '',
            tagline: 'text-base font-semibold text-default',
            terms: 'text-xs/5 text-muted text-center text-balance'
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'grid-cols-1 lg:grid-cols-3 justify-between divide-y lg:divide-y-0 lg:divide-x divide-default',
                body: 'lg:col-span-2 pb-6 lg:pb-0 lg:pr-6 justify-center',
                footer: 'lg:justify-center lg:items-center lg:p-6 lg:max-w-xs lg:w-full lg:mx-auto',
                features: 'lg:grid lg:grid-cols-2 lg:mt-12'
              },
              vertical: {
                footer: 'justify-end',
                priceWrapper: 'mt-6'
              }
            },
            variant: {
              solid: {
                root: 'bg-inverted',
                title: 'text-inverted',
                description: 'text-dimmed',
                price: 'text-inverted',
                discount: 'text-dimmed',
                billingCycle: 'text-dimmed',
                billingPeriod: 'text-dimmed',
                featureTitle: 'text-dimmed'
              },
              outline: {
                root: 'bg-default ring ring-default'
              },
              soft: {
                root: 'bg-elevated/50'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default'
              }
            },
            highlight: {
              true: {
                root: 'ring-2 ring-inset ring-primary'
              }
            },
            scale: {
              true: {
                root: 'lg:scale-[1.1] lg:z-[1]'
              }
            }
          },
          compoundVariants: [
            {
              orientation: 'horizontal',
              variant: 'soft',
              class: {
                root: 'divide-accented'
              }
            },
            {
              orientation: 'horizontal',
              variant: 'subtle',
              class: {
                root: 'divide-accented'
              }
            }
          ],
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})

更新日志

61b60— 功能:允许传递组件而不是名称 (#4766)

5cb65— 特性:导入 @nuxt/ui-pro 组件