Nuxt 3过渡在一个组件中不起作用

huangapple go评论42阅读模式
英文:

Nuxt 3 Transition is not working in a component

问题

我在Nuxt 3中创建了一个侧边栏,将其分为两个组件,分别是Sidebar和Hamburger。

我不明白为什么在Nuxt 3中组件中的Transition不起作用?

我还在这两个组件中使用了useState()组合来共享状态,请查看下面的代码:

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>

我认为在Nuxt 3的组件中应该可以使用过渡效果,但不起作用,请告诉我我漏掉了什么?非常感谢!

英文:

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&lt;Boolean&gt;(&#39;isNavOpen&#39;, () =&gt; false);

Hamburger.vue

&lt;template&gt;
&lt;div id=&quot;hamburger&quot; :class=&quot;{ &#39;active&#39;: hamburger }&quot; @click.prevent=&quot;toggle&quot;&gt;
&lt;a v-ripple class=&quot;cursor-pointer block align-self-center&quot;&gt;
&lt;i class=&quot;pi pi-bars text-xl&quot;&gt;&lt;/i&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;script setup lang=&quot;ts&quot;&gt;
const hamburger = useState(&#39;isNavOpen&#39;);
const toggle = () =&gt; {
hamburger.value = !hamburger.value;
}
&lt;/script&gt;

Sidebar.vue

 &lt;template&gt;
&lt;div class=&quot;sidebar&quot;&gt;
&lt;div class=&quot;sidebar-backdrop&quot; @click.prevent=&quot;toggle&quot; v-if=&quot;sidebar&quot;&gt;
&lt;Transition name=&quot;slide&quot;&gt;
&lt;div v-if=&quot;sidebar&quot;
class=&quot;sidebar-panel&quot;&gt;
&lt;slot&gt;&lt;/slot&gt;
&lt;/div&gt;
&lt;/Transition&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;script setup lang=&quot;ts&quot;&gt;
const sidebar = useState(&#39;isNavOpen&#39;);
const toggle = () =&gt; {
sidebar.value = !sidebar.value;
}
&lt;/script&gt;
&lt;style scoped&gt;
.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;
}
&lt;/style&gt;

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!

答案1

得分: 1

不要在<Transition>组件外部和内部的v-if中使用相同的变量。当您的<Transition>组件出现在模板中时,实际上没有v-if。组件就像它一直存在一样,因此没有什么需要过渡的,<Transition>内部的v-if在实际中不存在。要解决这个问题,只需从包围过渡组件的外部div中移除v-if,或将其放置在过渡组件内部。

英文:

Don't use same variable in v-if outside and inside transition component. When Your &lt;Transition&gt; 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.

答案2

得分: 0

我找到了我的解决方案。

首先,useState 应该写成这样:

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

其次,不要用 Transition 包装 sidebar-backdrop,实际代码应该是这样的:

<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>

第三,我使用了 slide-enter,应该是 slide-enter-from,实际代码看起来是这样的:

.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
}
英文:

I have found my solution.

Firstly, the useState should be written as like this:

export const useNavOpen = () =&gt; useState&lt;boolean&gt;(&#39;navOpen&#39;, () =&gt; false)

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

&lt;template&gt;
&lt;div class=&quot;sidebar&quot;&gt;
&lt;div class=&quot;sidebar-backdrop&quot; @click.prevent=&quot;toggle&quot; v-if=&quot;sidebar&quot;&gt;&lt;/div&gt;
&lt;Transition name=&quot;slide&quot;&gt;
&lt;div v-if=&quot;sidebar&quot; class=&quot;sidebar-panel&quot;&gt;
&lt;slot&gt;&lt;/slot&gt;
&lt;/div&gt;
&lt;/Transition&gt;
&lt;/div&gt;
&lt;/template&gt;

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
}

huangapple
  • 本文由 发表于 2023年2月6日 22:11:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75362430.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定