Skip to content
Advertisement

How to animate a wizard type form with Vue JS

I am trying to implement a simple animation with Vue but unsuccessful so far. I have two divs which are rendered depending on the value of a given data property

<!--Step 1-->
<div v-if="step == 1" :transition="'slide'">
  <select class="form-control"  v-model="id.category">
    <option value="null">Please Select</option>
    <option v-for="cat in cats" :value="cat.id">@{{cat.name}}</option>
  </select>
</div>

<!--Step 2-->
<div v-if="step==2" :transition="'slide'"  style="background: red">
  <select @change="fixImage(id.subcategory)" class="form-control quoteForm" v-model="id.subcategory">
    <option value="null">Please Select</option>
    <option v-for="subcat in filtered_subcat" :value="subcat.id">@{{subcat.name}}</option>
  </select>
</div>

I effectively have a “next button” that will increment the value of step and then show the relevant div. I would like to create like a slide type of effect whereby when the user clicks next, step 1 slides to the left and step 2 slides in. My animation css is as follows:

.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
  transform: translateX(10px);
  opacity: 0;
}

Can anyone point in the right direction?

Advertisement

Answer

Wrap the changing content in a <transition> component:

<transition name="slide-fade">
 <div v-if="step == 1">
     STEP 1 CONTENT
 </div>
</transition>

<transition name="slide-fade">
 <div v-if="step == 2">
     STEP 2 CONTENT
 </div>
</transition>

The name of the transition, slide-fade, matches the CSS you supplied. Since you probably want the sliding content to overlap, one should have position: absolute. For example, the content sliding out:

.slide-fade-leave-active {
  position: absolute;
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}

Here’s a Demo:

new Vue({
  el: "#app",
  data() {
    return {
        step: 1
    }
  }
});
.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  position: absolute;
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
  transform: translateX(10px);
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <!--Step 1-->

  <transition name="slide-fade">
    <div v-if="step == 1">
      STEP 1 CONTENT
    </div>
  </transition>

  <!--Step 2-->
  <transition name="slide-fade">
    <div  v-if="step == 2">
      STEP 2 CONTENT
    </div>
  </transition>

  <button @click="step++">
    Next >
  </button>
</div>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement