为什么我的 vue Leave 过渡不起作用?
Why my vue Leave transition not working?
我正在使用 vee validate 进行表单验证。我正在使用 vue transition 来显示这样的验证错误:
<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;
}
现在,当错误进入时,过渡正常,但当错误消失时,过渡不工作。
为什么会这样?
过渡正常。你看到它突然变成空白,因为没有 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>
如果你真的必须...
考虑额外代码的数量,但如果您真的必须这样做,则必须将 watch 添加到 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>
这是一个有点老的话题,但我想出了一个更简单的解决方案,它只需要最少的代码,适用于仍在寻找解决方案的每个人。
它的作用是在每次按下输入键(@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' 变量(变为 updateError($event)
),并在声明中接受它。然后,使用 srcElement
获取启动该按键事件的源元素(在我们的例子中是输入),并获取它的 name/class/id/whatever;取决于此,您可以修改其各自的变量(在我们的例子中为 error.name
和 error.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>
希望对您有所帮助!
我正在使用 vee validate 进行表单验证。我正在使用 vue transition 来显示这样的验证错误:
<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;
}
现在,当错误进入时,过渡正常,但当错误消失时,过渡不工作。 为什么会这样?
过渡正常。你看到它突然变成空白,因为没有 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>
如果你真的必须...
考虑额外代码的数量,但如果您真的必须这样做,则必须将 watch 添加到 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>
这是一个有点老的话题,但我想出了一个更简单的解决方案,它只需要最少的代码,适用于仍在寻找解决方案的每个人。
它的作用是在每次按下输入键(@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' 变量(变为 updateError($event)
),并在声明中接受它。然后,使用 srcElement
获取启动该按键事件的源元素(在我们的例子中是输入),并获取它的 name/class/id/whatever;取决于此,您可以修改其各自的变量(在我们的例子中为 error.name
和 error.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>
希望对您有所帮助!