As part of learning Vue, I tried implementing a simple step process with Vue. Step process can be used to implement a multi-step form with Vue or to implement a multi-step Quiz, Survey Form or anything of that sorts.

The implementation is fairly simple and dynamic. i.e. There can be any number of steps in the process and the vue code will be able to handle that.

Here is what we are looking to achieve in the HTML structure.

<step-wizard>
     <tab name="Step 1" :selected="true">
           This is step 1 of multi-step process.
     </tab>
     <tab name="Step 2">
           This is step 2 of multi-step process.
     </tab>
     <tab name="Step 3">
           This is step 3 of multi-step process.
     </tab>  
</step-wizard>

step-wizard is our parent vue component and there can be any number of tab (child component) inside this.

Here is the component declaration for step-wizard.

Vue.component('step-wizard',{

            template:`<div>
                <div class="tab-details">
                    <slot></slot>
                </div>

                <br/>
                <button @click="changeTab(currentActive--)" v-if="currentActive > 0">Previous</button>
                <button @click="changeTab(currentActive++)" v-if="currentActive < totalTabs - 1">Next</button>
                <button v-if="currentActive == totalTabs -1">Submit</button>
                
            </div>`,

            data(){
                return{
                    tabs: [],
                    currentActive: 0,
                    totalTabs: 0,
                }
            },

            created(){
                this.tabs = this.$children;
                
            },

            mounted(){
                this.totalTabs = this.tabs.length;
            },

            methods:{
                changeTab(currentActive){
                    this.tabs.forEach(tab => {
                       tab.isActive = false;
                    });
                    
                    this.tabs[this.currentActive].isActive = true;
                }
            }
        });

Let's go over the implementation

template: The template definition is simple, whatever markup we have inside step-wizard we slot it into the tab-details div. And we have three buttons for the step navigation.

data: We maintain the data of currentActive tab which be default is 0 and totalTabls.

created: Once we have our component created, we go ahead and get all the children component and store them in tabs array.

mounted: Once the component is mounted we get the number of tabs and store it in totalTabs data variable.

methods: We have a single method changeTab which handles the navigation of tabs. It accepts the makeTabActive as the parameter, This is the tab which we are looking to make active and rest all tabs we will hide from the screen.

Next up, here is how the child component (tab) declaration looks like

Vue.component('tab',{
            template: `<div v-show="isActive"><h3>{{name}}</h3><slot></slot></div>`,

            props: {
                name:{required: true},
                selected: { default: false}
            },

            data(){
                return{
                    isActive: false
                }
            },

            created(){
                this.isActive = this.selected
            }
        });

template: template declaration is simple, we just slot in whatever markup is there in tabs element.

props: We accept the name and selected attribute to tabs component.

data: isActive data property is used to track the status of tab which is active. Although we pass in selected as a property to this component. We make use of isActive since in Vue component property are immutable and to change the status we need to make use data variable or computed property.

That's about it.

Code:

https://github.com/tushargugnani/vue-examples/blob/master/vue-steps.html

Working Demo:

https://tushargugnani.github.io/vue-examples/vue-steps.html

Comments