Reputation: 8137
I have a custom animation that the regular Vue transition doesn't quite cover. I have it implemented elsewhere with a conditional v-bind:class
, but that doesn't work well for conditional v-if
blocks or v-for
groups.
I need to add a class ('open') one frame after the element is entered as with v-enter-to
, but I need it to never be removed from the element.
I then need it removed removed when leaving to trigger the closing animation.
Am I using Vue Transition wrong and this is perfectly possible within transition, or is there a way to add/remove the class around the enter/leave functionality?
.accordion {
overflow: hidden;
> div {
margin-bottom: -1000px;
transition: margin-bottom .3s cubic-bezier(.5,0,.9,.8),visibility 0s .3s,max-height 0s .3s;
max-height: 0;
overflow: hidden;
}
&::after {
content: "";
height: 0;
transition: height .3s cubic-bezier(.67,.9,.76,.37);
max-height: 35px;
}
&.open {
max-height: 8000px;
> div {
transition: margin-bottom .3s cubic-bezier(.24,.98,.26,.99);
margin-bottom: 0;
max-height: 100000000px;
position: relative;
}
&::after {
height: 35px;
max-height: 0;
transition: height .3s cubic-bezier(.76,.37,.67,.9),max-height 0s .3s;
}
}
}
<transition name="accordion" :duration="300">
<div class="accordion" v-if="equipmentSelections.length === 0">
<div>
<p>Begin by selecting equipment from the list</p>
</div>
</div>
</transition>
<transition-group name="accordion" :duration="300">
<div v-for="equipment in equipmentSelections" v-bind:key="equipment.unitNumber" class="accordion">
<div>
<h3 v-on:click="updateSelections(equipment)">{{equipment.unitNumber}}</h3>
</div>
</div>
</transition-group>
Upvotes: 1
Views: 987
Reputation: 5062
You can get more power out of the vue transition component by using the javascript hooks.
For example: Demo: https://codepen.io/KingKozo/pen/QWpBPza
HTML:
<div id="app">
<div>
<button type="button" @click="toggle">Toggle</button>
</div>
<transition name="label" v-on:enter="enter" v-on:before-leave="leave">
<div v-if="isOpen">Hi</div>
</transition>
</div>
CSS
.label-enter-active, .label-leave-active {
transition: opacity 1s;
}
.label-enter, .label-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.staying-visible {
background-color: red;
color: white;
}
Javascript
const vm = new Vue({
el: '#app',
data: {
isOpen: false
},
methods: {
enter(el){
el.classList.add("staying-visible")
},
leave(el){
el.classList.remove("staying-visible")
},
toggle(){
this.isOpen = !this.isOpen
}
}
})
In the example I provided I add a brand new class, "staying-visible", to the element on enter and remove it later on. In the example provided, I remove the class on "before-leave" so as to make the change visible but for your specific use case it seems like you can also just remove it during the 'leave' hook.
To learn more about how to use the javascript transition hooks, check out the official documentation: https://v2.vuejs.org/v2/guide/transitions.html#JavaScript-Hooks
Upvotes: 3