Search code examples
javascriptviewvuejs2transition

VUE :Transition elements on view change


I have what seems to be the simplest of problems but cannot get around it.

My goal is very simple : On view change I would like to transition some elements of the new view. Not the whole view, because I want to keep the background in place, so a <router-view> global transition doesn't do the trick here (it works btw).


Here is an simplified version of the code I have right now :

<template>
    <div class="fixedBackground">
        <transition name="slideIn">
            <div>
                <h1>Title</h1>
                <p>Subtitle</p>
            </div>
        </transition>
    </div>
</template>

<script>
    export default { 
        name: 'whatever'
    }
</script>

<style scoped>  
    .slideIn-enter-active, .slideIn-leave-active {
    transition: transform .3s ease, opacity .3s ease;
    }
    .slideIn-enter, .slideIn-leave-to {
        transform: translateX(-10vw);
        opacity: 0;
    }
    .slideIn-enter-to, .slideIn-leave {
        transform: translateX(0);
        opacity: 1;
    }
</style>

The transition as it is doesn't have any effect. I tried watching routes in App.vue to pass the active page as a prop and activate the transition when landing on the page, it didn't work. And now that I'm experimenting with even more complicated solutions it just feels like I'm missing the really easy way to do that :( by what I've read the code I have should work fine.


TLDR : I need to transition some elements on view change, but not the whole router-view.


Solution

  • You need a v-if or v-show inside your transition, a data variable, "show" in this example, to toggle visibility, and then toggle the "show" variable on created, or any other action like data returned from an API, etc.

    <template>
        <div class="fixedBackground">
            <transition name="slideIn">
                <div v-show="show">
                    <h1>Title</h1>
                    <p>Subtitle</p>
                </div>
            </transition>
        </div>
    </template>
    
    
    <script>
        export default { 
            name: 'whatever',
            data () {
                return {
                    show: false
                }
            },
            mounted () {
                this.show = true;
            }
        }
    </script>
    
    
    <style scoped>  
        .slideIn-enter-active, .slideIn-leave-active {
        transition: transform .3s ease, opacity .3s ease;
        }
        .slideIn-enter, .slideIn-leave-to {
            transform: translateX(-10vw);
            opacity: 0;
        }
        .slideIn-enter-to, .slideIn-leave {
            transform: translateX(0);
            opacity: 1;
        }
    </style>