将项目从Vue2迁移到Vue3时,过渡动画不起作用



我有一个在Vue2.7上的项目,正在将其移植到Vue3和vite。由于2.7中的compositionAPI支持,我几乎复制了确切的代码。一切都正常渲染,但现在突然之间,我的过渡动画不再像以前那样平滑下拉,甚至悬停的大小也很奇怪。

我一直在努力找出这里出了什么问题,但我并没有发现我写的东西和Vue3引起的中断之间有任何差异。

如果有人知道为什么这些动画和我的大部分造型不起作用,请告诉我!

干杯

我制作了一个CodeSandbox来编辑所有内容。

下拉.vue

<template>
<div>
<div
v-if="kind === 'products'"
class="_custom-select"
@mouseenter="open = true"
@mouseleave="open = false"
>
<div
style="display: flex"
:class="[open ? open : '', '_dropdown-title']"
@click="open = !open"
>
<p class="_title">Products</p>
<svg
:class="[open ? '_rotate-180' : '']"
style="width: 13px; margin-left: 6px"
xmlns="http://www.w3.org/2000/svg"
width="11.677"
height="6.676"
viewBox="0 0 11.677 6.676"
>
<path
d="M4.663,5.837.245,1.422A.835.835,0,0,1,1.427.244l5.006,5A.833.833,0,0,1,6.457,6.4L1.43,11.434A.835.835,0,0,1,.249,10.255Z"
transform="translate(11.677) rotate(90)"
fill="#7897fd"
/>
</svg>
</div>
<Transition name="slide">
<div v-if="open" :class="[sidebar ? '_transparent' : '', '_items']">
<a href="#" class="_product-icon"> Option2 </a>
<a href="#"> Option1 </a>
</div>
</Transition>
</div>
<div
v-if="kind === 'resources'"
class="_custom-select"
@mouseenter="open = true"
@mouseleave="open = false"
>
<div
style="display: flex"
:class="[open ? open : '', '_dropdown-title']"
@click="open = !open"
>
<p class="_title">Resources</p>
<svg
:class="[open ? '_rotate-180' : '']"
style="width: 13px; margin-left: 6px"
xmlns="http://www.w3.org/2000/svg"
width="11.677"
height="6.676"
viewBox="0 0 11.677 6.676"
>
<path
d="M4.663,5.837.245,1.422A.835.835,0,0,1,1.427.244l5.006,5A.833.833,0,0,1,6.457,6.4L1.43,11.434A.835.835,0,0,1,.249,10.255Z"
transform="translate(11.677) rotate(90)"
fill="#7897fd"
/>
</svg>
</div>
<Transition name="slide">
<div v-if="open" :class="[sidebar ? '_transparent' : '', '_items']">
<a href="https://google.com/" target="_blank">E-Learning</a>
<a href="#">FAQ</a>
</div>
</Transition>
</div>
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
props: {
/**
* @example
* "products" | "resources"
*/
kind: { type: String, default: "products" },
sidebar: { type: Boolean, default: false },
},
setup(props) {
const open = ref(false);
return {
open,
};
},
});
</script>
<style lang="sass" scoped>
p
all: unset
._custom-select
position: relative
text-align: left
outline: none
font-size: 1rem
text-decoration: none
._dropdown-title
display: flex
justify-content: center
align-items: center
// font-size: 20px
font-weight: bold
color: #fff
padding: 0.25em 2em
cursor: pointer
user-select: none
._items
position: absolute
background-color: #0D1F5D
left: 0
right: 0
top: 100%
display: flex
flex-direction: column
justify-content: center
align-items: center
color: #fff
z-index: 1
& a
color: #fff
text-decoration: none
width: 100%
// font-size: 1.25rem
font-weight: bold
text-align: center
padding: 0.75em 1em
cursor: pointer
user-select: none
&:hover
background-color: #2A3A72
._transparent
background-color: transparent
._product-icon
width: 100%
// height: 27px
._rotate-180
transform: rotate(180deg)
transition: 0.3s linear
.slide-enter-active
-moz-transition-duration: 0.3s
-webkit-transition-duration: 0.3s
-o-transition-duration: 0.3s
transition-duration: 0.3s
-moz-transition-timing-function: ease-in-out
-webkit-transition-timing-function: ease-in-out
-o-transition-timing-function: ease-in-out
transition-timing-function: ease-in-out
.slide-leave-active
-moz-transition-duration: 0.3s
-webkit-transition-duration: 0.3s
-o-transition-duration: 0.3s
transition-duration: 0.3s
-moz-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
-webkit-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
-o-transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
transition-timing-function: cubic-bezier(0, 1, 0.5, 1)
.slide-enter-to,
.slide-leave
max-height: 100px
overflow: hidden
.slide-enter,
.slide-leave-to
overflow: hidden
max-height: 0
</style>

Navbar.vue

<script>
import { defineComponent, ref, onMounted } from "vue";
import DropdownMenu from "./DropdownMenu.vue";
import HamburgerMenu from "./HamburgerMenu.vue";
export default defineComponent({
components: { DropdownMenu, HamburgerMenu },
setup() {
// const scrolledNav = ref(null)
const mobile = ref(false);
const mobileNav = ref(false);
const windowWidth = ref(null);
function toggleMobileNav() {
mobileNav.value = !mobileNav.value;
}
function checkScreen() {
windowWidth.value = window.innerWidth;
if (windowWidth.value <= 850) {
mobile.value = true;
return;
}
mobile.value = false;
mobileNav.value = false;
return;
}
onMounted(() => {
window.addEventListener("resize", checkScreen);
checkScreen();
});
function contactClicked() {
console.log("contact clicked");
}
return {
mobile,
mobileNav,
windowWidth,
toggleMobileNav,
checkScreen,
contactClicked,
};
},
});
</script>
<template>
<div class="_nav">
<nav>
<div class="_nav-header">
<a href="/"> IMAGE </a>
<div class="_icon">
<HamburgerMenu
:open="mobileNav"
@click="toggleMobileNav"
v-show="mobile"
/>
</div>
<div v-show="!mobile" class="_nav-inner">
<DropdownMenu kind="products" />
<DropdownMenu kind="resources" />
<a href="about" class="_about">About Us</a>
</div>
<div v-show="!mobile" class="_buttons">
<a href="/contact" class="_contact-button" @click="contactClicked">
Contact Us</a
>
<a href="signIn" class="_sign-in-button"> Sign In</a>
</div>
</div>
<div class="_sidebar">
<div
class="_sidebar-backdrop"
@click="mobileNav = false"
v-if="mobileNav"
></div>
<transition name="slide">
<div v-if="mobileNav" class="_sidebar-panel">
<DropdownMenu :sidebar="true" kind="products" />
<DropdownMenu :sidebar="true" kind="resources" />
<a href="about" class="_about">About Us</a>
<div class="_buttons-sidebar">
<a href="/contact" class="_contact-button"> Contact Us</a>
<a href="signIn" class="_sign-in-button"> Sign In</a>
</div>
</div>
</transition>
</div>
</nav>
</div>
</template>
<style lang="sass" scoped>
._nav
position: fixed
top: 0
left: 0
width: 100%
color: #fff
background-color: #0D1F5D
transition: 500ms ease all
z-index: 99
&-header
display: flex
justify-content: space-between
align-items: center
width: 100%
margin: 1em 0
nav
position: relative
display: flex
height: 5.5vh
min-height: 64px
transition: 500ms ease all
margin: 0 auto
@media(min-width: 1648px)
max-width: 1648px
._nav-inner
display: flex
justify-content: center
align-items: center
flex: 1
._logo
display: flex
justify-content: center
align-items: center
height: 100%
min-height: 26px
._about
text-decoration: none
font-weight: bold
color: #fff
._sign-in-button
text-decoration: none
display: flex
justify-content: center
align-items: center
width: max-content
// height: 100%
text-align: center
/* font-size: 1rem */
font-weight: bold
color: #fff
background-color: #962326
border: none
border-radius: 8px
box-shadow: none
padding: 6px 26px
transition: 0.3s ease
&:hover
background-color: #b32a2d
._contact-button
text-decoration: none
display: flex
justify-content: center
align-items: center
box-sizing: border-box
width: max-content
height: 100%
text-align: center
/* font-size: 1rem */
font-weight: bold
color: #fff
background-color: transparent
outline: 2px #fff solid
border-radius: 8px
padding: 4px 16px
transition: 0.3s ease
&:hover
background-color: #fff
color: #0D1F5D
._icon
display: flex
align-items: center
height: 100%
z-index: 99
._sidebar
&-backdrop
background-color: rgba(19, 15, 64, .4)
width: 100vw
height: 100vh
position: fixed
top: 0
left: 0
cursor: pointer
&-panel
overflow-y: auto
position: fixed
left: 0
top: 64px
bottom: 0
display: flex
flex-direction: column
justify-content: space-around
align-items: center
background-color: #130f40
width: 50%
// padding: 3em 2em
z-index: 999
._buttons
display: flex
align-items: center
gap: 2em
._buttons-sidebar
display: flex
flex-direction: column
align-items: center
gap: 1em
.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
@media only screen and (max-width: 1648px)
nav
padding: 0 4em
</style>

尝试使用.slide-enter-form而不是.slide-enter,使用.slide-leave-from而不是.slide-leave。点击此处了解更多

最新更新