VStepper
The VStepper component displays progress through numbered steps in a process. It supports linear and non-linear navigation, validation, and extensive customization of step appearance.
Basic Usage
<template>
<v-stepper v-model="step" :items="items">
<template #item.1>
<h3>Step 1 Content</h3>
</template>
<template #item.2>
<h3>Step 2 Content</h3>
</template>
<template #item.3>
<h3>Step 3 Content</h3>
</template>
</v-stepper>
</template>
<script setup>
import { ref } from 'vue'
const step = ref(1)
const items = [
{ title: 'Step 1', value: 1 },
{ title: 'Step 2', value: 2 },
{ title: 'Step 3', value: 3 }
]
</script>
Current active step value. Use with v-model.
items
StepperItem[]
default:"[]"
Array of step items. Each item can be a string or object with title, subtitle, and validation properties.
itemTitle
SelectItemKey
default:"'title'"
Property name or function to use for item titles.
itemValue
SelectItemKey
default:"'value'"
Property name or function to use for item values.
itemProps
SelectItemKey
default:"'props'"
Property name or function to extract additional props from items.
Places step labels below step icons instead of to the right.
Allows clicking on step headers to navigate to that step.
Allows navigating to any step regardless of completion status.
Removes the stepper’s elevation and background.
Hides the default next/prev action buttons.
Background color of the stepper.
Icon displayed for completed steps.
Icon displayed for editable steps.
Icon displayed for steps with errors.
Text for the previous button in actions.
Text for the next button in actions.
Color theme applied to the stepper.
Disables navigation controls.
selectedClass
string
default:"'v-stepper-item--selected'"
CSS class applied to the selected step.
mandatory
boolean | 'force'
default:"'force'"
Forces at least one step to be selected.
Step Item Object
type StepperItem = {
title?: string
subtitle?: string
value?: any
complete?: boolean
error?: boolean
editable?: boolean
icon?: IconValue
rules?: ValidationRule[]
}
type ValidationRule = () => string | boolean
Emitted when the active step changes.
default
{ prev: Function, next: Function }
Main content slot. Receives navigation functions.
actions
{ prev: Function, next: Function }
Slot to customize or replace the action buttons.
Slot to customize the entire header for a step.
Slot to customize step header items.
Slot to customize step icons.
Slot to customize step titles.
Slot to customize step subtitles.
Slot to customize the previous button.
Slot to customize the next button.
Named slot for specific step header.
Named slot for specific step content.
Navigation Patterns
Linear Stepper
<template>
<v-stepper v-model="step" :items="items">
<template #item.1>
<v-card>
<v-card-text>Complete this step first</v-card-text>
</v-card>
</template>
<template #item.2>
<v-card>
<v-card-text>Then this step</v-card-text>
</v-card>
</template>
</v-stepper>
</template>
Non-Linear Stepper
<template>
<v-stepper
v-model="step"
:items="items"
non-linear
editable
>
<!-- Step content -->
</v-stepper>
</template>
With Validation
<template>
<v-stepper v-model="step" :items="items">
<template #item.1>
<v-form v-model="valid">
<!-- Form fields -->
</v-form>
</template>
</v-stepper>
</template>
<script setup>
import { ref } from 'vue'
const step = ref(1)
const valid = ref(false)
const items = [
{
title: 'Account Info',
value: 1,
rules: [() => valid.value || 'Please complete the form']
},
{ title: 'Confirmation', value: 2 }
]
</script>
Alternative Labels
<template>
<v-stepper
v-model="step"
:items="items"
alt-labels
>
<!-- Step content -->
</v-stepper>
</template>
Custom Actions
<template>
<v-stepper v-model="step" :items="items" hide-actions>
<template #item.1>
<v-card>
<v-card-text>Step content</v-card-text>
<v-card-actions>
<v-btn @click="step = 2">Continue</v-btn>
</v-card-actions>
</v-card>
</template>
</v-stepper>
</template>
Examples
Step with Subtitle
<template>
<v-stepper v-model="step" :items="items">
<template #item.1>
<h3>Personal Information</h3>
</template>
</v-stepper>
</template>
<script setup>
const items = [
{
title: 'Account',
subtitle: 'Create your account',
value: 1
}
]
</script>
Error State
<template>
<v-stepper v-model="step" :items="items">
<!-- Step content -->
</v-stepper>
</template>
<script setup>
const items = [
{
title: 'Step 1',
value: 1,
error: true
}
]
</script>
Complete State
<template>
<v-stepper v-model="step" :items="items">
<!-- Step content -->
</v-stepper>
</template>
<script setup>
const items = [
{
title: 'Step 1',
value: 1,
complete: true
},
{
title: 'Step 2',
value: 2
}
]
</script>
Custom Icons
<template>
<v-stepper
v-model="step"
:items="items"
complete-icon="mdi-check-circle"
error-icon="mdi-alert-circle"
edit-icon="mdi-pencil"
>
<!-- Step content -->
</v-stepper>
</template>
Programmatic Navigation
<template>
<v-stepper v-model="step" :items="items">
<template #default="{ prev, next }">
<v-btn @click="prev">Previous</v-btn>
<v-btn @click="next">Next</v-btn>
</template>
</v-stepper>
</template>
Accessibility
- Step headers are clickable buttons when
editable is true
- Proper ARIA attributes for step states
- Visual indicators for complete, error, and active states
- Keyboard navigation support through standard button controls