
Recently I saw someone asking how to achieve a simple multi-step form with modern web development practises. Of course, my mind instantly went to VueJS and having built a few multi-step forms in my time I weighed in with my approach.
A word of warning, I am not by any stretch of the imagination an expert with VueJS, nor should you take the examples listed in this post as working or 'good'. The below is simply my personal experiences with this, and how I have achieved it in the past.
Also, it is good to keep in mind that there are many different ways to work with Vue. I prefer to use the "single file component" approach. That is, that every component has one file; that is the approach I shall be taking in this post. Other approaches include inline templates, full classes and plugins.
Getting Started
I always like to get started with something like this by sorting out the logic in my head. Now, to me, logically a multi-step form will need a way to define different 'states' without a page load.
I like to achieve this with simple data properties such as 'showStepOne
', 'showStepTwo
' etc. While I understand that this is quite verbose, but the flip side of that is that it is extremely readable, and you know exactly what step you're in as a developer.
So, let's start our Vue component like so:
The Data
Vue is a data-centric framework, which means that every form needs places to store it's data. In Vue these are often data properties references in v-model. Let's add some data properties to our data() method on our Vue Component to use for our v-model's in our template.
The Template
Now that we know what our data structure looks like, we can start the template part of things.
The Methods
All of the above is pretty useless without the methods which power it all. We need methods which:
- Saves data to our API
- Change the current step
- Change the visility of the loading spinner
With that in mind, let's write some basic goTo methods which do this for us.
Finally, we will also need a final method to "finalise" the form. This typically ends the transaction and redirects the user away.
Closing thoughts
Of course this could be all done a lot differently. Our showStepOne
, showStepTwo
, and showStepThree
data properties could simply be condensed into a single "step
" property.
The individual steps in the template could be child components (<WizardStepOne>
, <WizardStepTwo>
etc), each with their own save()
methods to save the data, pushing the spinner state and current page state back to the parent, to move onto another child component. For a larger form I would advocate this method.
The goToStepOne
, goToStepTwo
and goToStepThree
methods could be condensed into a single goToStep(step)
method, which talks to child components etc.
Final Full Component:
With all of that being said, if we put all of the above together, we should get something like the below. Note that I have also added a navigation to allow users to go back and forward between steps through a breadcrumb type system.
A word of warning, this was written solely for this demo and post, has not been tested and I give no guarantees that this will work.
What are your thoughts? You can let me know on Twitter: @MadMikeyB