Reputation: 2897
In my app, clicking a modal's close button makes it disappear with a fade animation whereas swiping it down makes it disappear with a swipe animation. This is done by changing the modal's <transition name>
based on event.
The same thing doesn't seem to work with a transition group. Am I doing something wrong, or is it actually not possible?
Template:
<transition-group :name="itemTransition">
<div
v-for="item in items"
:key="item.id"
v-hammer:swipe.up="() => onSwipeUp(notification.id)"
>
</div>
</transition-group>
Script:
export default {
data () {
return {
applySwipeTransition: false
}
},
computed: {
itemTransition () {
return this.applySwipeTransition ? 'swipe' : 'fade'
}
},
methods: {
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.applySwipeTransition = false
})
}
}
}
CSS:
.fade-leave-active {
animation: fade-out .75s;
}
.swipe-leave-active {
animation: slide-up .25s;
}
Upvotes: 3
Views: 793
Reputation: 7729
The problem lies in the timing of component update. You are switching the transition mode back to fade
in the same update cycle as when the element is closed. Thus, when the next component update is triggered (by removal of the item), the transition is already switched back to fade
. At this point, you may have guessed that all that needs to be done, is to switch the transition back in the next update, triggered by removal of the item:
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.$nextTick(()=>{
this.applySwipeTransition = false
})
})
}
Since there are no reasons to wait for component update to close the item, you can simplify the code a bit:
onSwipeUp (id) {
this.applySwipeTransition = true
this.closeItem(id)
this.$nextTick(() => {
this.applySwipeTransition = false
})
}
Here is your working sandbox: https://codesandbox.io/s/vue-template-forked-60lkk?file=/src/App.vue
Upvotes: 3
Reputation: 163
So, I've worked around with your CSS by manually changing the name
of the <transition-group
to either fade
or swipe
to see if the there's a problem with the CSS animations.
Verdict: The fade
works. swipe
only transitions the list-item
off the page by a click and drag, not true swipe, if that concerns you (by the way, my swipe is MacOS swipe - two-finger, no click)
Still, without changing the CodePen, the issue seems to be with your computed
property where there's nothing telling the name
to change dynamically even though you've bound it to a computed
property - the logic for itemTransition()
seems to always default to fade
because the applySwipeTransition
would never equal to "swipe", given that the CSS does work when you manually change name
to swipe
(see "Verdict)".
To see where the underlying issue was, I worked around with your itemTransition()
:
computed: {
itemTransition() {
return this.applySwipeTransition ? "fade" : "swipe";
},
Switching the order of the fade
and swipe
now makes swipe
work. I hope this gives you some insight into the issue. You may need to create a custom Vue directive or event to handle the swipe / fade logic if needed.
Upvotes: 0