Vue Router 与 transition 组件结合,如何实现页面切换时旧页面驻留效果?

我在使用transition实现页面的切换效果,期望的效果是当用户点击跳转时,当前页面A驻留不移动,新页面B从右往左推入,在新页面推入的过程中A始终可见,直至B将其覆盖。但是在实现过程中发现,页面A会直接消失且背景变为白色,而新页面B正常推入。

<template>
    <router-view v-slot="{ Component, route }">
        <transition  mode="out-in"  name="slide" appear>
                <div :key="route?.name" style="height: 100%;width: 100%;">
                    <component :is="Component" />
                </div>
        </transition>
    </router-view>
</template>
.slide-enter-from {
    // position: absolute;
    // left: 0;
    // top: 0;
  opacity: 0;
  transform: translateX(100%); 
}
.slide-enter-active {
  transition: all 0.5s ease; 
}
.slide-enter-to {

  opacity: 1;
  transform: translateX(0); 
}

.slide-leave-from {
    // position: absolute;
    // left: 0;
    // top: 0;
  opacity: 1;
  transform: translateX(0); 
}
.slide-leave-active {
  transition: all 0.1s ease;
}
.slide-leave-to {
  opacity: 0;
  transform: translateX(0); 
}
阅读 2.3k
avatarAI BotBETA

要实现你描述的页面切换效果,其中旧页面A在新页面B推入时保持可见直至被覆盖,你需要确保页面A在动画过程中不会被Vue Router的<router-view>组件自动移除。Vue Router在切换路由时,默认会移除旧的<router-view>组件内容并添加新的内容,但是通过使用<transition>组件和:key绑定,你可以控制这个行为。

在你的代码中,你已经正确地使用了:key绑定来区分不同的路由,但是你可能需要确保CSS样式允许页面A在动画过程中保持可见。此外,mode="out-in"意味着旧组件先完成过渡,新组件再开始过渡。对于你的需求,这可能不是必需的,因为你想让两个组件同时动画。

首先,请移除多余的mode="out-in"属性(它只应该出现一次)。然后,确保你的CSS样式允许页面A在动画期间可见。你的CSS代码看起来基本正确,但是可能需要添加一些额外的样式来确保页面A在动画期间不被隐藏或覆盖。

这里是一个更新后的示例:

<template>
  <router-view v-slot="{ Component, route }">
    <transition name="slide" appear>
      <div :key="route.name" style="position: relative; height: 100%; width: 100%; overflow: hidden;">
        <component :is="Component" />
      </div>
    </transition>
  </router-view>
</template>

<style scoped>
.slide-enter-active, .slide-leave-active {
  transition: all 0.5s ease;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.slide-enter-from {
  transform: translateX(100%);
}
.slide-enter-to, .slide-leave-from {
  transform: translateX(0);
}
.slide-leave-to {
  transform: translateX(-100%); /* 或者其他值,根据你的需要 */
}
</style>

在这个例子中,我移除了一个重复的mode="out-in"属性,并添加了position: relative;到包含<component><div>上。同时,我也将.slide-leave-totransform值更改为-100%,这样页面A就会向左移动而不是向右移动(根据你的描述,你可能想要这样的效果)。

注意,使用overflow: hidden;可以防止在动画期间出现内容溢出。这对于确保页面A在动画期间不会显示在页面B的下方是很重要的。

最后,请确保你的Vue Router配置正确,并且<router-view>组件被放置在正确的位置。如果问题仍然存在,请检查你的Vue版本和Vue Router版本是否与你的代码兼容。

3 个回答

移除 mode="in-out"

另外你的div可能加上position:absolute来固定位置,要不然两个页面过渡过程中会把第二个页面挤到滚动条下面。

给页面离开设置动画,用 transition-delay 延迟播放动画。

stackblitz

把 appear 属性去掉试试?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏