I'm seeing some behavior with Vue transitions that I don't understand. It'll be easier to explain by showing an example:
Given the following component:
<transition :name="transitionName">
<div v-if="showMe">Hey</div>
</transition>
<button @click="transitionName='slide-left'; showMe = false">Left</button>
And that the following is true:
- There are css classes in place for the transition names
.slide-left
and.slide-right
which does what their names imply. - The initial state of
transitionName
isslide-right
- The initial state of
showMe
is true
I would expect the div to slide left when the button is clicked. However, it slides right.
A full reproducible is available here:
var demo = new Vue({
el: '#demo',
data: {
showMe: true,
transitionName: 'slide-right'
}
});
#demo {
display: flex;
justify-content: center;
flex-direction: column;
width: 20%;
margin: 100px auto;
text-align: center;
}
.buttons {
display: flex;
justify-content: space-between;
}
.slide-right-enter-active,
.slide-left-enter-active,
.slide-right-leave-active,
.slide-left-leave-active {
transition: all 1s ease-in-out;
}
.slide-left-enter,
.slide-left-leave-to {
transform: translateX(-100%);
}
.slide-right-enter,
.slide-right-leave-to {
transform: translateX(100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<transition :name="transitionName">
<div v-if="showMe">Hey</div>
</transition>
<div class="buttons">
<button @click="transitionName='slide-left'; showMe = false">left</button>
<button @click="transitionName='slide-right'; showMe = !showMe">right</button>
</div>
</div>
It contains both a "left" and "right" button, but the component will slide "right" regardless of which one you click.
I can fix it by changing the button's callback to this:
this.transitionName = 'slide-left';
Vue.nextTick(() => {
this.showMe = false;
});
But I'm wondering why nextTick
is necessary here, and whether there is a better way to solve the problem in general.