用法
步骤项
使用 items
prop,它是一个对象数组,包含以下属性
title?: string
description?: AvatarProps
content?: string
icon?: string
value?: string | number
disabled?: boolean
slot?: string
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = ref<StepperItem[]>([
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
},
{
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
},
{
title: 'Checkout',
description: 'Confirm your order'
}
])
</script>
<template>
<UStepper :items="items" class="w-full" />
</template>
颜色
使用 color
prop 更改步进器的颜色。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = ref<StepperItem[]>([
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
},
{
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
},
{
title: 'Checkout',
description: 'Confirm your order'
}
])
</script>
<template>
<UStepper color="neutral" :items="items" class="w-full" />
</template>
尺寸
使用 size
prop 更改步进器的尺寸。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = ref<StepperItem[]>([
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
},
{
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
},
{
title: 'Checkout',
description: 'Confirm your order'
}
])
</script>
<template>
<UStepper size="xl" :items="items" class="w-full" />
</template>
方向
使用 orientation
prop 更改步进器的方向。默认为 horizontal
。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = ref<StepperItem[]>([
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
},
{
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
},
{
title: 'Checkout',
description: 'Confirm your order'
}
])
</script>
<template>
<UStepper orientation="vertical" :items="items" class="w-full" />
</template>
禁用
使用 disabled
prop 禁用步骤间的导航。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = ref<StepperItem[]>([
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
},
{
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
},
{
title: 'Checkout',
description: 'Confirm your order'
}
])
</script>
<template>
<UStepper disabled :items="items" />
</template>
示例
带控件
您可以使用按钮为步进器添加额外的控件。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items: StepperItem[] = [
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
}, {
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
}, {
title: 'Checkout',
description: 'Confirm your order'
}
]
const stepper = useTemplateRef('stepper')
</script>
<template>
<div class="w-full">
<UStepper ref="stepper" :items="items">
<template #content="{ item }">
<Placeholder class="aspect-video">
{{ item.title }}
</Placeholder>
</template>
</UStepper>
<div class="flex gap-2 justify-between mt-4">
<UButton
leading-icon="i-lucide-arrow-left"
:disabled="!stepper?.hasPrev"
@click="stepper?.prev()"
>
Prev
</UButton>
<UButton
trailing-icon="i-lucide-arrow-right"
:disabled="!stepper?.hasNext"
@click="stepper?.next()"
>
Next
</UButton>
</div>
</div>
</template>
控制活动步骤项
您可以使用 default-value
prop 或带有步骤项索引的 v-model
指令控制活动步骤项。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
import { onMounted, ref } from 'vue'
const items: StepperItem[] = [
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
}, {
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
}, {
title: 'Checkout',
description: 'Confirm your order'
}
]
const active = ref(0)
// Note: This is for demonstration purposes only. Don't do this at home.
onMounted(() => {
setInterval(() => {
active.value = (active.value + 1) % items.length
}, 2000)
})
</script>
<template>
<UStepper v-model="active" :items="items" class="w-full">
<template #content="{ item }">
<Placeholder class="aspect-video">
This is the {{ item?.title }} step.
</Placeholder>
</template>
</UStepper>
</template>
value
,您也可以传入其中一个步骤项的 value
。带 content slot
使用 #content
slot 自定义每个步骤项的内容。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items: StepperItem[] = [
{
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
}, {
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
}, {
title: 'Checkout',
description: 'Confirm your order'
}
]
</script>
<template>
<UStepper ref="stepper" :items="items" class="w-full">
<template #content="{ item }">
<Placeholder class="aspect-video">
This is the {{ item?.title }} step.
</Placeholder>
</template>
</UStepper>
</template>
带自定义 slot
使用 slot
属性自定义特定的步骤项。
地址
在此添加您的地址
配送
设置您偏好的配送方式
结账
确认您的订单
<script setup lang="ts">
import type { StepperItem } from '@nuxt/ui'
const items = [
{
slot: 'address' as const,
title: 'Address',
description: 'Add your address here',
icon: 'i-lucide-house'
}, {
slot: 'shipping' as const,
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'i-lucide-truck'
}, {
slot: 'checkout' as const,
title: 'Checkout',
description: 'Confirm your order'
}
] satisfies StepperItem[]
</script>
<template>
<UStepper :items="items" class="w-full">
<template #address>
<Placeholder class="aspect-video">
Address
</Placeholder>
</template>
<template #shipping>
<Placeholder class="aspect-video">
Shipping
</Placeholder>
</template>
<template #checkout>
<Placeholder class="aspect-video">
Checkout
</Placeholder>
</template>
</UStepper>
</template>
API
Props
Prop | 默认值 | 类型 |
---|---|---|
as |
|
此组件应渲染为何种元素或组件。 |
items |
| |
尺寸 |
|
|
颜色 |
|
|
方向 |
|
步进器的方向。 |
defaultValue |
初始渲染时应处于活动状态的步骤的值。当您不需要控制步骤的状态时使用。 | |
disabled |
| |
linear |
|
步骤是否必须按顺序完成。 |
modelValue |
| |
ui |
|
Slots
Slot | 类型 |
---|---|
indicator |
|
title |
|
description |
|
content |
|
Emits
Event | 类型 |
---|---|
next |
|
prev |
|
update:modelValue |
|
Expose
您可以使用以下方法访问类型化的组件实例useTemplateRef
.
<script setup lang="ts">
const stepper = useTemplateRef('stepper')
</script>
<template>
<UStepper ref="stepper" />
</template>
这将使您能够访问以下内容
名称 | 类型 |
---|---|
next | () => void |
prev | () => void |
hasNext | Ref<boolean> |
hasPrev | Ref<boolean> |
主题
export default defineAppConfig({
ui: {
stepper: {
slots: {
root: 'flex gap-4',
header: 'flex',
item: 'group text-center relative w-full',
container: 'relative',
trigger: 'rounded-full font-medium text-center align-middle flex items-center justify-center font-semibold group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2',
indicator: 'flex items-center justify-center size-full',
icon: 'shrink-0',
separator: 'absolute rounded-full group-data-[disabled]:opacity-75 bg-accented',
wrapper: '',
title: 'font-medium text-default',
description: 'text-muted text-wrap',
content: 'size-full'
},
variants: {
orientation: {
horizontal: {
root: 'flex-col',
container: 'flex justify-center',
separator: 'top-[calc(50%-2px)] h-0.5',
wrapper: 'mt-1'
},
vertical: {
header: 'flex-col gap-4',
item: 'flex text-start',
separator: 'start-[calc(50%-1px)] -bottom-[10px] w-0.5'
}
},
size: {
xs: {
trigger: 'size-6 text-xs',
icon: 'size-3',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-1.5'
},
sm: {
trigger: 'size-8 text-sm',
icon: 'size-4',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-2'
},
md: {
trigger: 'size-10 text-base',
icon: 'size-5',
title: 'text-sm',
description: 'text-sm',
wrapper: 'mt-2.5'
},
lg: {
trigger: 'size-12 text-lg',
icon: 'size-6',
title: 'text-base',
description: 'text-base',
wrapper: 'mt-3'
},
xl: {
trigger: 'size-14 text-xl',
icon: 'size-7',
title: 'text-lg',
description: 'text-lg',
wrapper: 'mt-3.5'
}
},
color: {
primary: {
trigger: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary focus-visible:outline-primary',
separator: 'group-data-[state=completed]:bg-primary'
},
secondary: {
trigger: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary focus-visible:outline-secondary',
separator: 'group-data-[state=completed]:bg-secondary'
},
success: {
trigger: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success focus-visible:outline-success',
separator: 'group-data-[state=completed]:bg-success'
},
info: {
trigger: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info focus-visible:outline-info',
separator: 'group-data-[state=completed]:bg-info'
},
warning: {
trigger: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning focus-visible:outline-warning',
separator: 'group-data-[state=completed]:bg-warning'
},
error: {
trigger: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error focus-visible:outline-error',
separator: 'group-data-[state=completed]:bg-error'
},
neutral: {
trigger: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted focus-visible:outline-inverted',
separator: 'group-data-[state=completed]:bg-inverted'
}
}
},
compoundVariants: [
{
orientation: 'horizontal',
size: 'xs',
class: {
separator: 'start-[calc(50%+16px)] end-[calc(-50%+16px)]'
}
},
{
orientation: 'horizontal',
size: 'sm',
class: {
separator: 'start-[calc(50%+20px)] end-[calc(-50%+20px)]'
}
},
{
orientation: 'horizontal',
size: 'md',
class: {
separator: 'start-[calc(50%+28px)] end-[calc(-50%+28px)]'
}
},
{
orientation: 'horizontal',
size: 'lg',
class: {
separator: 'start-[calc(50%+32px)] end-[calc(-50%+32px)]'
}
},
{
orientation: 'horizontal',
size: 'xl',
class: {
separator: 'start-[calc(50%+36px)] end-[calc(-50%+36px)]'
}
},
{
orientation: 'vertical',
size: 'xs',
class: {
separator: 'top-[30px]',
item: 'gap-1.5'
}
},
{
orientation: 'vertical',
size: 'sm',
class: {
separator: 'top-[38px]',
item: 'gap-2'
}
},
{
orientation: 'vertical',
size: 'md',
class: {
separator: 'top-[46px]',
item: 'gap-2.5'
}
},
{
orientation: 'vertical',
size: 'lg',
class: {
separator: 'top-[54px]',
item: 'gap-3'
}
},
{
orientation: 'vertical',
size: 'xl',
class: {
separator: 'top-[62px]',
item: 'gap-3.5'
}
}
],
defaultVariants: {
size: 'md',
color: 'primary'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
stepper: {
slots: {
root: 'flex gap-4',
header: 'flex',
item: 'group text-center relative w-full',
container: 'relative',
trigger: 'rounded-full font-medium text-center align-middle flex items-center justify-center font-semibold group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2',
indicator: 'flex items-center justify-center size-full',
icon: 'shrink-0',
separator: 'absolute rounded-full group-data-[disabled]:opacity-75 bg-accented',
wrapper: '',
title: 'font-medium text-default',
description: 'text-muted text-wrap',
content: 'size-full'
},
variants: {
orientation: {
horizontal: {
root: 'flex-col',
container: 'flex justify-center',
separator: 'top-[calc(50%-2px)] h-0.5',
wrapper: 'mt-1'
},
vertical: {
header: 'flex-col gap-4',
item: 'flex text-start',
separator: 'start-[calc(50%-1px)] -bottom-[10px] w-0.5'
}
},
size: {
xs: {
trigger: 'size-6 text-xs',
icon: 'size-3',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-1.5'
},
sm: {
trigger: 'size-8 text-sm',
icon: 'size-4',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-2'
},
md: {
trigger: 'size-10 text-base',
icon: 'size-5',
title: 'text-sm',
description: 'text-sm',
wrapper: 'mt-2.5'
},
lg: {
trigger: 'size-12 text-lg',
icon: 'size-6',
title: 'text-base',
description: 'text-base',
wrapper: 'mt-3'
},
xl: {
trigger: 'size-14 text-xl',
icon: 'size-7',
title: 'text-lg',
description: 'text-lg',
wrapper: 'mt-3.5'
}
},
color: {
primary: {
trigger: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary focus-visible:outline-primary',
separator: 'group-data-[state=completed]:bg-primary'
},
secondary: {
trigger: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary focus-visible:outline-secondary',
separator: 'group-data-[state=completed]:bg-secondary'
},
success: {
trigger: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success focus-visible:outline-success',
separator: 'group-data-[state=completed]:bg-success'
},
info: {
trigger: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info focus-visible:outline-info',
separator: 'group-data-[state=completed]:bg-info'
},
warning: {
trigger: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning focus-visible:outline-warning',
separator: 'group-data-[state=completed]:bg-warning'
},
error: {
trigger: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error focus-visible:outline-error',
separator: 'group-data-[state=completed]:bg-error'
},
neutral: {
trigger: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted focus-visible:outline-inverted',
separator: 'group-data-[state=completed]:bg-inverted'
}
}
},
compoundVariants: [
{
orientation: 'horizontal',
size: 'xs',
class: {
separator: 'start-[calc(50%+16px)] end-[calc(-50%+16px)]'
}
},
{
orientation: 'horizontal',
size: 'sm',
class: {
separator: 'start-[calc(50%+20px)] end-[calc(-50%+20px)]'
}
},
{
orientation: 'horizontal',
size: 'md',
class: {
separator: 'start-[calc(50%+28px)] end-[calc(-50%+28px)]'
}
},
{
orientation: 'horizontal',
size: 'lg',
class: {
separator: 'start-[calc(50%+32px)] end-[calc(-50%+32px)]'
}
},
{
orientation: 'horizontal',
size: 'xl',
class: {
separator: 'start-[calc(50%+36px)] end-[calc(-50%+36px)]'
}
},
{
orientation: 'vertical',
size: 'xs',
class: {
separator: 'top-[30px]',
item: 'gap-1.5'
}
},
{
orientation: 'vertical',
size: 'sm',
class: {
separator: 'top-[38px]',
item: 'gap-2'
}
},
{
orientation: 'vertical',
size: 'md',
class: {
separator: 'top-[46px]',
item: 'gap-2.5'
}
},
{
orientation: 'vertical',
size: 'lg',
class: {
separator: 'top-[54px]',
item: 'gap-3'
}
},
{
orientation: 'vertical',
size: 'xl',
class: {
separator: 'top-[62px]',
item: 'gap-3.5'
}
}
],
defaultVariants: {
size: 'md',
color: 'primary'
}
}
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
ui: {
stepper: {
slots: {
root: 'flex gap-4',
header: 'flex',
item: 'group text-center relative w-full',
container: 'relative',
trigger: 'rounded-full font-medium text-center align-middle flex items-center justify-center font-semibold group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2',
indicator: 'flex items-center justify-center size-full',
icon: 'shrink-0',
separator: 'absolute rounded-full group-data-[disabled]:opacity-75 bg-accented',
wrapper: '',
title: 'font-medium text-default',
description: 'text-muted text-wrap',
content: 'size-full'
},
variants: {
orientation: {
horizontal: {
root: 'flex-col',
container: 'flex justify-center',
separator: 'top-[calc(50%-2px)] h-0.5',
wrapper: 'mt-1'
},
vertical: {
header: 'flex-col gap-4',
item: 'flex text-start',
separator: 'start-[calc(50%-1px)] -bottom-[10px] w-0.5'
}
},
size: {
xs: {
trigger: 'size-6 text-xs',
icon: 'size-3',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-1.5'
},
sm: {
trigger: 'size-8 text-sm',
icon: 'size-4',
title: 'text-xs',
description: 'text-xs',
wrapper: 'mt-2'
},
md: {
trigger: 'size-10 text-base',
icon: 'size-5',
title: 'text-sm',
description: 'text-sm',
wrapper: 'mt-2.5'
},
lg: {
trigger: 'size-12 text-lg',
icon: 'size-6',
title: 'text-base',
description: 'text-base',
wrapper: 'mt-3'
},
xl: {
trigger: 'size-14 text-xl',
icon: 'size-7',
title: 'text-lg',
description: 'text-lg',
wrapper: 'mt-3.5'
}
},
color: {
primary: {
trigger: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary focus-visible:outline-primary',
separator: 'group-data-[state=completed]:bg-primary'
},
secondary: {
trigger: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary focus-visible:outline-secondary',
separator: 'group-data-[state=completed]:bg-secondary'
},
success: {
trigger: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success focus-visible:outline-success',
separator: 'group-data-[state=completed]:bg-success'
},
info: {
trigger: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info focus-visible:outline-info',
separator: 'group-data-[state=completed]:bg-info'
},
warning: {
trigger: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning focus-visible:outline-warning',
separator: 'group-data-[state=completed]:bg-warning'
},
error: {
trigger: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error focus-visible:outline-error',
separator: 'group-data-[state=completed]:bg-error'
},
neutral: {
trigger: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted focus-visible:outline-inverted',
separator: 'group-data-[state=completed]:bg-inverted'
}
}
},
compoundVariants: [
{
orientation: 'horizontal',
size: 'xs',
class: {
separator: 'start-[calc(50%+16px)] end-[calc(-50%+16px)]'
}
},
{
orientation: 'horizontal',
size: 'sm',
class: {
separator: 'start-[calc(50%+20px)] end-[calc(-50%+20px)]'
}
},
{
orientation: 'horizontal',
size: 'md',
class: {
separator: 'start-[calc(50%+28px)] end-[calc(-50%+28px)]'
}
},
{
orientation: 'horizontal',
size: 'lg',
class: {
separator: 'start-[calc(50%+32px)] end-[calc(-50%+32px)]'
}
},
{
orientation: 'horizontal',
size: 'xl',
class: {
separator: 'start-[calc(50%+36px)] end-[calc(-50%+36px)]'
}
},
{
orientation: 'vertical',
size: 'xs',
class: {
separator: 'top-[30px]',
item: 'gap-1.5'
}
},
{
orientation: 'vertical',
size: 'sm',
class: {
separator: 'top-[38px]',
item: 'gap-2'
}
},
{
orientation: 'vertical',
size: 'md',
class: {
separator: 'top-[46px]',
item: 'gap-2.5'
}
},
{
orientation: 'vertical',
size: 'lg',
class: {
separator: 'top-[54px]',
item: 'gap-3'
}
},
{
orientation: 'vertical',
size: 'xl',
class: {
separator: 'top-[62px]',
item: 'gap-3.5'
}
}
],
defaultVariants: {
size: 'md',
color: 'primary'
}
}
}
})
]
})