最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why my vue Leave transition not working? - Stack Overflow

programmeradmin1浏览0评论

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?

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?

Share Improve this question asked Mar 17, 2018 at 20:48 Rakesh KohaliRakesh Kohali 2752 gold badges5 silver badges17 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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 bees 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./vue"></script>
<script src="https://cdn.jsdelivr/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./vue"></script>
<script src="https://cdn.jsdelivr/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>

This is kinda' an old topic, but I figured out a much more easier solution that will work with a minimal amount of code, for everybody who's still searching for one.

What this does, is checking for the error message every time you press a key in the input (the @keypress event), saves it into a variable, which is displayed alongside the actual error message in the div, using a OR, making sure that the error.message variable never gets undefined. That OR guarantees that there will be something displayed, even if the actual error (the one given by VeeValidate) isn't available, up until the animation is finished.

Vue.use(VeeValidate);
new Vue({
  el: '#demo',

  data() {
    return {
      error: {
        name: null,
      },
    }
  },

  methods: {
    updateError() {
      const message = this.errors.first('name');

      if (message) { // check if message isn't undefined
        this.error.name = message;
      }
    },
  },
});
.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 {
  transform: translateX(10px);
  opacity: 0;
}
<script src="https://unpkg./vue"></script>
<script src="https://cdn.jsdelivr/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'" @keypress="updateError()"><!-- added keypress event -->
  <transition name="slide-fade">
    <div v-show="errors.has('name')">Errors: {{ errors.first('name') || error.name }}</div><!-- OR -->
  </transition>
</div>

And if you have multiple inputs you can do this: pass the '$event' variable in the updateError() function (being updateError($event)), and accept it in the declaration. Then, use srcElement to get the source element that started that keypress event (in our case an input), and fetch its name/class/id/whatever; depending on that, you can modify its respective variable (in our case error.name and error.email). The rest is straight forward.

Vue.use(VeeValidate);
new Vue({
  el: '#demo',

  data() {
    return {
      error: {
        name: null,
        email: null,
      },
    }
  },

  methods: {
    updateError(e) {
      const input = e.srcElement.name;
      const message = this.errors.first(input);

      if (message) { // check if message isn't undefined
        if (input === 'name') {
          this.error.name = message;
        } else if (input === 'email') {
          this.error.email = message;
        }
      }
    },
  },
});
.row {
  display: flex;
  flex-wrap: wrap;
}

.col {
  flex: 0 0 45%;
  max-width: 45%;
}

.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 {
  transform: translateX(10px);
  opacity: 0;
}
<script src="https://unpkg./vue"></script>
<script src="https://cdn.jsdelivr/npm/vee-validate@latest/dist/vee-validate.js"></script>

<div id="demo" class="row">
  <div class="col">
    Type a name and then erase. And then type again.
    <input type="text" name="name" v-validate="'required'" @keypress="updateError($event)">
    <!-- added keypress event -->
    <transition name="slide-fade">
      <div v-show="errors.has('name')">Errors: {{ errors.first('name') || error.name }}</div>
      <!-- OR -->
    </transition>
  </div>

  <div class="col" style="border-left: 2px solid black; padding-left: 10px">
    Type an email and then erase. And then type again.
    <input type="text" name="email" v-validate="'required'" @keypress="updateError($event)">
    <!-- added keypress event -->
    <transition name="slide-fade">
      <div v-show="errors.has('email')">Errors: {{ errors.first('email') || error.email }}</div>
      <!-- OR -->
    </transition>
  </div>
</div>

I hope this helped you!

发布评论

评论列表(0)

  1. 暂无评论