Визарды
useWizard(steps, options?) — composable для многошаговых форм, построенный поверх defineMachine. Машина wizard'а генерируется автоматически из массива шагов.
function useWizard<TContext>(
steps: WizardStep<TContext>[],
options?: WizardOptions,
): WizardInstance<TContext>Шаги визарда
Поля WizardStep:
id
string. Уникальный идентификатор шага (внутри становится именем состояния).
label
string?. Отображаемая метка.
component
Component?. Vue-компонент, рендерящийся для этого шага.
canProceed
(ctx) => boolean | Promise<boolean>. Условие для next() и goTo() вперёд; может быть асинхронным. Получает реальный, живой контекст wizard'а — то, что успели слить в него onEnter/onLeave.
onEnter
(ctx) => void | Partial<TContext>. Вызывается, когда wizard входит в этот шаг. Верните частичный объект, чтобы слить его в контекст — например, задать значение по умолчанию.
onLeave
(ctx) => void | Partial<TContext>. Вызывается, когда wizard покидает этот шаг. Верните частичный объект, чтобы слить его в контекст — обычное место для сохранения данных, собранных на шаге (например, полей формы), до того, как canProceed на следующем шаге их прочитает.
Опции визарда
Поля WizardOptions:
id
string? · по умолчанию: автогенерируется. Id машины, регистрируемый в MachineStore (когда установлен VueMachinePlugin) и отображаемый в DevTools. Задайте его явно, если нужен стабильный, предсказуемый id (например, чтобы найти wizard через useMachineStore().get(id)); иначе каждый useWizard() получает свой уникальный id автоматически.
initialStep
number · по умолчанию: 0. Индекс начального шага.
allowSkip
boolean · по умолчанию: false. Пропускать canProceed при goTo() вперёд.
circular
boolean · по умолчанию: false. next() возвращается от последнего шага к первому.
Возвращаемое значение
currentStep
Ref<WizardStep>. Объект текущего активного шага.
currentIndex
ComputedRef<number>. Индекс текущего шага (от нуля).
totalSteps
number. Общее число шагов.
progress
ComputedRef<number>. От 0 до 1 на основе текущего индекса.
isFirst
ComputedRef<boolean>. true на первом шаге.
isLast
ComputedRef<boolean>. true на последнем шаге.
history
Ref<string[]>. ID посещённых шагов.
context
Readonly<Ref<TContext>>. Накопленный контекст — то, что успели слить в него onEnter/onLeave.
next()
Promise<boolean>. Продвигает вперёд; сначала вызывает canProceed; возвращает false, если заблокировано.
prev()
void. Назад (без guard).
goTo(id)
Promise<boolean>. Переход к шагу по id; учитывает canProceed, если не allowSkip.
reset()
void. Возврат к начальному шагу.
Пример
<script setup lang="ts">
import { useWizard } from '@macrulez/vue-state-machine'
import type { WizardStep } from '@macrulez/vue-state-machine'
import StepInfo from './StepInfo.vue'
import StepAddress from './StepAddress.vue'
import StepPayment from './StepPayment.vue'
interface CheckoutCtx {
name: string
email: string
address: string
}
const steps: WizardStep<CheckoutCtx>[] = [
{
id: 'info',
label: 'Your info',
component: StepInfo,
// Заполняется собственным onLeave шага StepAddress ниже, ещё до того как
// этот код выполнится в canProceed *следующего* шага — см. "context" в
// возвращаемом значении выше.
canProceed: (ctx) => !!ctx.name && !!ctx.email,
},
{
id: 'address',
label: 'Delivery',
component: StepAddress,
canProceed: (ctx) => !!ctx.address,
// Верните частичный объект, чтобы слить собранные данные формы в контекст —
// например, прочитав их из ref, который StepAddress обновляет через v-model,
// или из выпущенного им emit.
onLeave: (): Partial<CheckoutCtx> => ({ address: addressFieldRef.value }),
},
{
id: 'payment',
label: 'Payment',
component: StepPayment,
onEnter: () => trackEvent('payment_step_entered'),
},
]
const { currentStep, context, progress, isFirst, isLast, next, prev } = useWizard(steps)
</script>
<template>
<div>
<progress :value="progress" max="1" />
<component :is="currentStep.component" :context="context" />
<nav>
<button :disabled="isFirst" @click="prev">Back</button>
<button v-if="!isLast" @click="next">Next</button>
<button v-else @click="submit">Place order</button>
</nav>
</div>
</template>Правила для canProceed
- Может возвращать
booleanилиPromise<boolean> - Если возвращает
false,next()/goTo()вперёд возвращаютfalse, и wizard остаётся на текущем шаге - Если выбрасывает исключение, результат тот же — возвращается
false, ошибка логируется вconsole.errorв dev-режиме prev()иgoTo()назад никогда не проверяютcanProceedallowSkip: trueотключаетcanProceedтолько дляgoTo();next()проверяет его всегда