Vue Form Wizard
Vue Form Wizard is a Vue.js component designed to simplify the creation and management of multi-step forms or tabbed interfaces, often referred to as 'wizards'. It provides a flexible, dependency-free solution for splitting complex forms into manageable steps, improving user experience by guiding them through a process. The current stable version is 0.8.4. While its release cadence isn't strictly defined, patches and minor updates have been released intermittently, suggesting an active maintenance approach. Key differentiators include its complete lack of external dependencies (beyond Vue itself), built-in support for features like keyboard navigation (WAI-ARIA), scoped slots for extensive customization, integration with validation libraries like Vuelidate, and handling of asynchronous step changes and validations. It supports both horizontal and vertical layouts and offers various event hooks for controlling step transitions.
Common errors
-
[Vue warn]: Unknown custom element: <form-wizard> - did you register the component correctly?
cause The `FormWizard` component has not been registered with Vue either globally or locally within the parent component.fixGlobally: `import FormWizard from 'vue-form-wizard'; app.component('form-wizard', FormWizard);`. Locally: `components: { FormWizard }`. -
TypeError: Cannot read properties of undefined (reading 'TabContent')
cause Attempting to access `FormWizard.TabContent` when `FormWizard` is undefined or not correctly imported.fixEnsure `FormWizard` is correctly imported as a default import: `import FormWizard from 'vue-form-wizard';`. -
Form wizard appears unstyled or with incorrect layout.
cause The necessary CSS file for `vue-form-wizard` has not been imported.fixAdd `import 'vue-form-wizard/dist/vue-form-wizard.min.css'` to your application's entry file or the component where the wizard is used.
Warnings
- gotcha The `TabContent` component is exposed as a property of the default `FormWizard` component (`FormWizard.TabContent`) rather than a direct named export. This can lead to incorrect import statements.
- breaking The way scoped slots for `tab-content` were handled changed. Older versions might have different syntax or expectations for slot usage, requiring updates to templates.
- gotcha Styling for `vue-form-wizard` requires a separate CSS import. Neglecting this will result in unstyled components.
- gotcha When integrating with Vue Router, a `route` prop must be passed to tabs that are handled by the router. Incorrect or missing `route` props will prevent proper routing behavior within the wizard.
- gotcha Asynchronous validation using `beforeChange` expects a promise that resolves with a boolean for success or rejects with a message for failure. Misinterpreting the return type (e.g., returning only a boolean from an async function) can lead to unexpected navigation behavior.
Install
-
npm install vue-form-wizard -
yarn add vue-form-wizard -
pnpm add vue-form-wizard
Imports
- FormWizard
const FormWizard = require('vue-form-wizard')import FormWizard from 'vue-form-wizard' import 'vue-form-wizard/dist/vue-form-wizard.min.css'
- TabContent
import TabContent from 'vue-form-wizard/TabContent'
import { FormWizard, TabContent } from 'vue-form-wizard' - VueFormWizard
Vue.use(FormWizard)
import FormWizard from 'vue-form-wizard'; import 'vue-form-wizard/dist/vue-form-wizard.min.css'; Vue.component('form-wizard', FormWizard);
Quickstart
import { createApp } from 'vue';
import FormWizard from 'vue-form-wizard';
import 'vue-form-wizard/dist/vue-form-wizard.min.css';
const app = createApp({
template: `
<div id="app">
<form-wizard @on-complete="onComplete" :start-index="0">
<tab-content title="Personal details" icon="ti-user">
<p>Step 1: Enter your personal information.</p>
<input type="text" placeholder="Name" v-model="formData.name" />
</tab-content>
<tab-content title="Payment details" icon="ti-credit-card">
<p>Step 2: Provide payment information.</p>
<input type="text" placeholder="Card Number" v-model="formData.cardNumber" />
</tab-content>
<tab-content title="Last step" icon="ti-check">
<p>Step 3: Review and submit.</p>
<pre>{{ JSON.stringify(formData, null, 2) }}</pre>
</tab-content>
</form-wizard>
</div>
`,
components: {
FormWizard,
TabContent: FormWizard.TabContent // Access TabContent via FormWizard
},
data() {
return {
formData: {
name: '',
cardNumber: ''
}
};
},
methods: {
onComplete() {
alert('Yay. Done!');
console.log('Form completed with data:', this.formData);
}
}
});
app.mount('#app');