5

我正在使用 vee validate 进行表单验证。我在显示验证错误时使用 vue 转换,如下所示:

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

现在,当错误进入过渡时,过渡正在工作,但当错误消失时,过渡不起作用。为什么会这样?

4

2 回答 2

4

过渡正在发挥作用。你突然看到它是空白的,因为没有什么errors.first('name')可显示的了。

当你添加一些其他字符串时errors.first('name'),比如说Error:,它变得很清楚。

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>


如果你真的必须...

考虑额外代码的数量,但如果你真的必须这样做,你将不得不在's 的值上添加一个监视并在它发生时记录第一个错误。input

vee-validate 不提供错误的侦听器,因此它与当前一样好。请参阅下面的演示。

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>

于 2018-03-17T21:50:49.857 回答
1

这是一个老话题,但我想出了一个更简单的解决方案,它可以使用最少的代码,适合仍在寻找的每个人。

它的作用是在每次按下输入(@keypress事件)中的一个键时检查错误消息,将其保存到一个变量中,该变量与 div 中的实际错误消息一起显示,使用 OR,确保error.message变量永远不会得到undefined. OR 保证会显示一些内容,即使实际错误(由 VeeValidate 给出的错误)不可用,直到动画完成。

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.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'" @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>

如果您有多个输入,您可以这样做:在updateError()函数中传递 '$event' 变量 (becoming updateError($event)),并在声明中接受它。然后,用于srcElement获取启动该按键事件的源元素(在我们的例子中是一个输入),并获取它的名称/类/id/whatever;根据这一点,您可以修改其各自的变量(在我们的示例中为error.nameerror.email)。其余的都是直截了当的。

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

我希望这对你有帮助!

于 2019-04-23T08:08:18.267 回答