Eugene10
Eugene10

Reputation: 121

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!

Upvotes: 2

Views: 394

Answers (2)

Eugene10
Eugene10

Reputation: 121

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
}

Upvotes: 0

Mises
Mises

Reputation: 4623

Don't use same variable in v-if outside and inside transition component. When Your <Transition> component appears in template, it has no v-if in reality. Component is there like he was always there, so it has nothing to transit, v-if inside transition not exists in reality. So to solve it, just remove v-if from outer div around transition component. Or place it inside a transition component.

Upvotes: 1

Related Questions