oliverbusk's avatar

Vue3 - Transition not working on enter, only on leave

Hi there.

I have this simple flash element which I am showing on success:

<template>
 <div
        class="fixed inset-0 z-50 flex items-end justify-center px-4 py-6 pointer-events-none sm:p-6 sm:items-start sm:justify-end">
        <transition
            appear
            enter-active-class="transform ease-out duration-300 transition delay-300"
            enter-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
            enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
            leave-active-class="transition ease-in duration-100"
            leave-class="opacity-100"
            leave-to-class="opacity-0">
            <div
                v-show="$page.props.flash.success && show"
                class="max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden"
                @mouseleave="show = false">
                <div class="p-4">
                    <div class="flex items-start">
                        <div class="ml-3 w-0 flex-1 pt-0.5">
                            <div>
                                <p class="mt-1 text-sm text-gray-500">
                                    {{ $page.props.flash.success }}
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </transition>
    </div>
</template>
<script>
export default {
    data() {
        return {
            show: true,
        }
    },
    watch: {
        '$page.props.flash': {
            handler() {
                this.show = true
            },
            deep: true,
        },
    },
}
</script>

The small flash message appears instantly (without any "transition" applied) to it. Whenever the @mouseleave is triggered, it successfully "transitions out".

I am not sure why the transition is not applied on-enter/on-appear. Can someone help me? :)

0 likes
1 reply
Brandon Eichhorn's avatar
Level 4

enter-class and leave-class do not exist to my knowledge and you have no active transitions in the enter-active-class prop, which then results in no transitions. This should do the magic:

enter-active-class="transform ease-out duration-300 translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"

Full code:

        <Transition
            enter-active-class="transform ease-out duration-300 transition delay-300 translate-y-2 opacity-0 
            sm:translate-y-0 sm:translate-x-2"
            enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
            leave-active-class="transition opacity-100 ease-in duration-100"
            leave-to-class="opacity-0"
            appear>
            <div
                v-show="$page.props.flash.success && show"
                class="max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden"
                @mouseleave="show = false">
                <div class="p-4">
                    <div class="flex items-start">
                        <div class="ml-3 w-0 flex-1 pt-0.5">
                            <div>
                                <p class="mt-1 text-sm text-gray-500">
                                    {{ $page.props.flash.success }}
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </transition>

I understand your confusion as your code does make more sense, but how it works is that v-enter-from is the starting state for the enter, its added before the element is even removed.

After that you go on to the v-enter-active state, which is applied during the entire entering phase.

Read more about these classes and their states on the official VueJS documentation:

https://vuejs.org/guide/built-ins/transition.html#css-based-transitions

One cool little hint is that there are tons of CSS animation libraries out there which you can simply include in your css folder or copy the transition classes to build really cool animations. I personally love animate.style!

1 like

Please or to participate in this conversation.