Search code examples
javascriptvue.jsvee-validate

Why my vue Leave transition not working?


I am using vee validate for form validation. i am using vue transition on displaying validations errors like this:

 <input type="text" name="name" v-validate="'required'">
<transition name="slide-fade">
  <div v-show="errors.has('name')">{{ errors.first('name') }}</div>
</transition>

Css:

    .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;
}

Now, when an error is entering the transition is working but when the error is disappearing transition is not working. why is this happening?


Solution

  • The transition is working. You see it suddenly blank because there's no errors.first('name') to show anymore.

    When you add some other string along errors.first('name'), say Error:, it becomes clear.

    Vue.use(VeeValidate);
    new Vue({
      el: '#demo'
    })
    .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;
    }
    <script src="https://unpkg.com/vue"></script>
    <script src="https://cdn.jsdelivr.net/npm/vee-validate@latest/dist/vee-validate.js"></script>
    
    <div id="demo">
      Type something and then erase. And then type again.
      <input type="text" name="name" v-validate="'required'">
      <transition name="slide-fade">
        <div v-show="errors.has('name')">Errors: {{ errors.first('name') }}</div>
      </transition>
    </div>


    If you really must...

    Consider the amount of additional code, but if you really must do it, you would have to add a watch to the input's value and record the first error when it happens.

    vee-validate does not provide listeners to erros, so this is as good as it currently gets. See demo below.

    Vue.use(VeeValidate);
    new Vue({
      el: '#demo',
      data: {
        name: "Erase me",
        nameError: ""
      },
      watch: {
        name() {
          // two ticks at least, because vee-validate takes one tick to validate
          Vue.nextTick().then(Vue.nextTick()).then(() => {
            if (this.errors.has('name')) { this.nameError = this.errors.first('name'); }
          });
        }
      }
    })
    .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;
    }
    <script src="https://unpkg.com/vue"></script>
    <script src="https://cdn.jsdelivr.net/npm/vee-validate@latest/dist/vee-validate.js"></script>
    
    <div id="demo">
      Erase and error will appear. Type again and error will leave.<br>
      <input type="text" name="name" v-validate="'required'" v-model="name">
      <transition name="slide-fade">
        <div v-show="errors.has('name')">Errors: {{ nameError }}</div>
      </transition>
    </div>