Vue Transitions

by Loque

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<div id="app">
  <div class="container">
    <div class="sample">
      <transition-group name="fade" tag="div" class="form-row">
        <div v-bind:class="col_md" :key="1" class="fade-item">
          <label for="cropType" class="col-form-label-sm font-weight-bold">Select Learn Javascript </label>
          <select class="form-control" v-on:change="selectTodo" id="cropType" v-model="pickedCropType" @change="getCropsByType()">
              <option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
                {{todo.text}}
              </option>
            </select>
        </div>
      <div v-bind:class="col_md" :key="2" class="fade-item">
        <label for="cropCulture" class="col-form-label-sm font-weight-bold">2. Second</label>
        <select class="form-control" id="cropCulture">
     <option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
                {{todo.text}}
              </option>
            </select>
      </div>
        <div class="form-group col-md-4 fade-item" v-if="showCropStageList" v-bind:class="{styleObject }" :key="3">
          <label for="cropStage" class="col-form-label-sm font-weight-bold">3. Third</label>
          <select class="form-control" id="cropStage">
                <option v-for="(todo, index) in todos" :key="index" :value="todo.id" >
                {{todo.text}}
              </option>
              </select>
        </div>
      </transition-group>
    </div>
  </div>

</div>

CSS

.sample {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

.fade-item {
  transition: all 0.5s;
  display:inline-block;
}

.fade-enter {
  opacity: 0;
  transform: translateX(-130px);

}

.fade-enter-active {
  transition: all 1.5s;
}

.fade-leave-to {
  transform: translateX(130px);
  opacity: 0;
  flex: 0 0 20%;
}

.fade-leave-active {
  transition: all 1s;
}


li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}

Vue

new Vue({
  el: "#app",
  data: {
    todos: [
      { id:1 ,text: "Learn JavaScript", done: false },
      { id:2 ,text: "Learn Vue", done: false },
      { id:3 ,text: "Play around in JSFiddle", done: true },
      { id:4 ,text: "Build something awesome", done: true }
    ],
    col_md: 'form-group col-md-6',
    styleObject: {
          display: 'none'
        },
    showCropStageList: false,
    pickedCropType: ''
  },
  methods: {
  	getCropsByType: function () {},
  	toggle: function(todo){
    	todo.done = !todo.done
    },
    selectTodo: function(e) {
    	let selectValue = e.target.options[e.target.selectedIndex].text
      if (selectValue === 'Learn Vue') {
        this.col_md = 'form-group col-md-4';
        this.$nextTick(() => { //delay display the third div before first two div finish animation
        	setTimeout(()=>{
            this.styleObject.display = 'unset';
            this.showCropStageList = true;
          }, 500)

        })
        
      }
      else {

        this.showCropStageList = false;
        this.styleObject.display = 'none';
        this.$nextTick(() => { //delay apply `md-6` to first two div before 3rd div finish animation
        	setTimeout(()=>{
          	this.col_md = 'form-group col-md-6';
          }, 1000)
        	
        })
        
        this.cropStageList = null;

      }
    }
  }
})