英文:
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<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!
答案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 <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.
答案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 = () => 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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论