Search code examples
nuxt.jsvuejs3nuxt3.jsvue-transitions

Nuxt 3 Transition is not working in a component


I am doing a sidebar in Nuxt 3 and I have separated the sidebar into two components, namely Sidebar and Hamburger.

I do not understand why does the Transition in a component in Nuxt 3 is not working?

I am also using useState() composable to share a state in these two components, please look at my code below:

useStates.ts

export const isNavOpen = useState<Boolean>('isNavOpen', () => false);

Hamburger.vue

<template>
    <div id="hamburger" :class="{ 'active': hamburger }" @click.prevent="toggle">
        <a v-ripple class="cursor-pointer block align-self-center">
            <i class="pi pi-bars text-xl"></i>
        </a>
    </div>
</template>

<script setup lang="ts">
const hamburger = useState('isNavOpen');

const toggle = () => {
    hamburger.value = !hamburger.value;
}
</script>

Sidebar.vue

 <template>
        <div class="sidebar">
            <div class="sidebar-backdrop" @click.prevent="toggle" v-if="sidebar">
                <Transition name="slide">
                    <div v-if="sidebar"
                         class="sidebar-panel">
                        <slot></slot>
                    </div>
                </Transition>
            </div>
        </div>
</template>

<script setup lang="ts">
    const sidebar = useState('isNavOpen');
    
    const toggle = () => {
        sidebar.value = !sidebar.value;
    }
</script>

<style scoped>
.slide-enter-active,
.slide-leave-active
{
    transition: transform 0.2s ease;
}

.slide-enter,
.slide-leave-to {
    transform: translateX(-100%);
    transition: all 150ms ease-in 0s
}

.sidebar-backdrop {
    background-color: rgba(0,0,0,.5);
    width: 100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    cursor: pointer;
}

.sidebar-panel {
    overflow-y: auto;
    background-color: #130f40;
    position: fixed;
    left: 0;
    top: 0;
    height: 100vh;
    z-index: 999;
    padding: 3rem 20px 2rem 20px;
    width: 300px;
}
</style>

I thought the transition should be working in a component in Nuxt 3, please let know what did I miss out? Thank you in advanced!


Solution

  • I have found my solution.

    Firstly, the useState should be written as like this:

    export const useNavOpen = () => useState<boolean>('navOpen', () => false)
    

    Secondly, do not wrap sidebar-backdrop with the Transition, the actual code should look like this:

    <template>
    <div class="sidebar">
        <div class="sidebar-backdrop" @click.prevent="toggle" v-if="sidebar"></div>
        <Transition name="slide">
            <div v-if="sidebar" class="sidebar-panel">
                <slot></slot>
            </div>
        </Transition>
    </div>
    </template>
    

    Thirdly, I used slide-enter, it should be slide-enter-from, the actual code looks like this:

    .slide-enter-active,
    .slide-leave-active
    {
        transition: transform 0.2s ease;
    }
    
    .slide-enter-from,
    .slide-leave-to {
        transform: translateX(-100%);
        transition: all 150ms ease-in 0s
    }