料金プラン

料金プランのリストをレスポンシブグリッドレイアウトで表示します。

使用法

PricingPlansコンポーネントは、PricingPlanコンポーネントのリストをデフォルトスロットまたはplansプロパティのいずれかを使用して表示する柔軟なレイアウトを提供します。

<template>
  <UPricingPlans>
    <UPricingPlan
      v-for="(plan, index) in plans"
      :key="index"
      v-bind="plan"
    />
  </UPricingPlans>
</template>
グリッド列は計画の数に基づいて自動的に計算されます。これはplansプロパティだけでなく、デフォルトのスロットでも動作します。

Plans

plansプロパティをPricingPlanコンポーネントのプロパティを持つオブジェクトの配列として使用します。

Solo
Tailored for indie hackers.
$249
  • One developer
  • Lifetime access
Startup
Best suited for small teams.
$499
  • Up to 5 developers
  • Everything in Solo
Organization
Ideal for larger teams and organizations.
$999
  • Up to 20 developers
  • Everything in Startup
<script setup lang="ts">
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans :plans="plans" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans :plans="plans" />
</template>

Orientation

orientationプロパティを使用してPricingPlansの向きを変更します。デフォルトはhorizontalです。

Solo
Tailored for indie hackers.
  • One developer
  • Lifetime access
$249
Startup
Best suited for small teams.
  • Up to 5 developers
  • Everything in Solo
$499
Organization
Ideal for larger teams and organizations.
  • Up to 20 developers
  • Everything in Startup
$999
<script setup lang="ts">
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans orientation="vertical" :plans="plans" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans orientation="vertical" :plans="plans" />
</template>
デフォルトスロットの代わりにplansプロパティを使用すると、プランのorientationが自動的に逆になり、horizontalからvertical、その逆も同様です。

Compact

compactプロパティを使用して、1つのプランが視覚的なバランスを改善するためにスケーリングされたときに、プラン間のパディングを減らします。

Solo
Tailored for indie hackers.
$249
  • One developer
  • Lifetime access
Startup
Best suited for small teams.
$499
  • Up to 5 developers
  • Everything in Solo
Organization
Ideal for larger teams and organizations.
$999
  • Up to 20 developers
  • Everything in Startup
<script setup lang="ts">
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    scale: true,
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans compact :plans="plans" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    scale: true,
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans compact :plans="plans" />
</template>

Scale

scaleプロパティを使用して、1つの平面が拡大縮小されたときに平面間の間隔を調整し、視覚的なバランスを改善します。

Solo
Tailored for indie hackers.
$249
  • One developer
  • Lifetime access
Startup
Best suited for small teams.
$499
  • Up to 5 developers
  • Everything in Solo
Organization
Ideal for larger teams and organizations.
$999
  • Up to 20 developers
  • Everything in Startup
<script setup lang="ts">
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    scale: true,
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans scale :plans="plans" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { PricingPlanProps } from '@nuxt/ui'

const plans = ref<PricingPlanProps[]>([
  {
    title: 'Solo',
    description: 'Tailored for indie hackers.',
    price: '$249',
    features: [
      'One developer',
      'Lifetime access'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Startup',
    description: 'Best suited for small teams.',
    price: '$499',
    scale: true,
    features: [
      'Up to 5 developers',
      'Everything in Solo'
    ],
    button: {
      label: 'Buy now'
    }
  },
  {
    title: 'Organization',
    description: 'Ideal for larger teams and organizations.',
    price: '$999',
    features: [
      'Up to 20 developers',
      'Everything in Startup'
    ],
    button: {
      label: 'Buy now'
    }
  }
])
</script>

<template>
  <UPricingPlans scale :plans="plans" />
</template>

例

これらの例はNuxt Contentを使用していますが、コンポーネントは任意のコンテンツ管理システムと統合できます。

ページ内

ページでPricingPlansコンポーネントを使用して、価格ページを作成します。

pages/pricing/index.vue
<script setup lang="ts">
const { data: plans } = await useAsyncData('plans', () => queryCollection('plans').all())
</script>

<template>
  <UPage>
    <UPageHero title="Pricing" />

    <UPageBody>
      <UContainer>
        <UPricingPlans :plans="plans" />
      </UContainer>
    </UPageBody>
  </UPage>
</template>
この例では、@nuxt/contentモジュールのqueryCollectionを使用してplansをフェッチします。

API

Props

Prop Default Type
as
'div'
any

The element or component this component should render as.

plans
PricingPlanProps[]
orientation
'horizontal'
"horizontal" | "vertical"

The orientation of the pricing plans.

compact
false
boolean

When true, the plans will be displayed without gap.

scale
false
boolean

When true, the plans will be displayed with a larger gap. Useful when one plan is scaled. Doesn't work with compact.

ui
{ base?: any; }

スロット

Slot Type
badge
{ ui: object; }
title
{}
description
{}
price
{}
discount
{}
billing
{ ui: object; }
features
{}
button
{ ui: object; }
header
{}
body
{}
footer
{}
tagline
{}
terms
{}
default
{}

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    pricingPlans: {
      base: 'flex flex-col gap-y-8',
      variants: {
        orientation: {
          horizontal: 'lg:grid lg:grid-cols-[repeat(var(--count),minmax(0,1fr))]',
          vertical: ''
        },
        compact: {
          false: 'gap-x-8'
        },
        scale: {
          true: ''
        }
      },
      compoundVariants: [
        {
          compact: false,
          scale: true,
          class: 'lg:gap-x-13'
        }
      ]
    }
  }
})
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: {
        pricingPlans: {
          base: 'flex flex-col gap-y-8',
          variants: {
            orientation: {
              horizontal: 'lg:grid lg:grid-cols-[repeat(var(--count),minmax(0,1fr))]',
              vertical: ''
            },
            compact: {
              false: 'gap-x-8'
            },
            scale: {
              true: ''
            }
          },
          compoundVariants: [
            {
              compact: false,
              scale: true,
              class: 'lg:gap-x-13'
            }
          ]
        }
      }
    })
  ]
})

Changelog

No recent changes