Vue进入过渡效果无法正常工作

4
我正在处理一个项目中,需要为一些组件添加进入和离开的动画效果。当组件进入屏幕时,它必须从底部进入,当组件离开时,它必须朝上离开。期望的行为是,当我改变组件标签的 :is 属性时,当前组件向上移动,下一个组件从底部进入。代码如下:
<template>
  <div class="home">
    <transition name="section">
      <component :is="activeSection"></component>
    </transition>
  </div>
</template>

<script>
import comp1 from './comp1';
import comp2 from './comp2';

export default {
  components: {
    comp1,
    comp2
  },
  data() {
    activeSection: 'comp1'
  }
</script>

<style scoped>
  .section-enter {
    top: 100vh;
  }
  .section-enter-to {
    top: 0vh;
  }
  .section-enter-active {
    animation-name: 'slideIn';
    animation-duration: 1s;
  }
  .section-leave {
    top: 0vh;
  }
  .section-leave-active {
    animation-name: 'slideOut';
    animation-duration: 1s;
  }
  .section-leave-to {
    top: -100vh;
  }


  @keyframes slideIn {
    from {
      top: 100vh;
    }
    to {
      top: 0
    }
  }

  @keyframes slideOut {
    from {
      top: 0vh;
    }
    to {
      top: -100vh;
    }
  }
</style>

但实际行为是第一个组件向上移动,但第二个组件立即出现而没有动画效果。
如果我一次只渲染一个组件(不销毁一个并使用相同的操作渲染另一个),则一切都可以完美地工作。我不知道发生了什么事情。

1
请问您能否将这个放到 CodeSandbox 等平台上,以便更容易地重现和查看? - Gowri
嗨,在我的情况下,我只需要在我的转换中添加一个 appear 属性。希望这可以帮助其他遇到此问题的人! - l-portet
2个回答

5

你的 CSS 存在一些问题。

CSS 过渡和 CSS 动画

可以使用 CSS 过渡CSS 动画 来实现过渡。在这种情况下,你的 CSS 错误地混合了两个概念。

特别是,slideIn 关键帧和 .section-enter/.section-enter-to 规则实际上执行了相同的任务,将 .section 移入视图。然而,这缺少了一个非零时间的 transition 规则来动画化变化,因此变化会立即发生。对于 slideOut 关键帧和 leave 规则也存在同样的问题。

.section-enter {
  top: 100vh;
}
.section-enter-to {
  top: 0;
}
.section-enter-active {
  transition: .5s; /* MISSING RULE */
}

.section-leave {
  top: 0;
}
.section-leave-to {
  top: -100vh;
}
.section-leave-active {
  transition: .5s; /* MISSING RULE */
}

删除关键帧,添加缺失的规则(如上所示)将导致工作CSS过渡效果。

演示1

使用CSS动画

或者,您可以使用CSS动画的关键帧,其中动画仅由*-active规则应用,并且不使用*-enter/*-leave规则。请注意,您的问题在animation-name:'slideIn';中包含了不必要的引号,这是无效的语法,并且会被静默忽略(没有动画发生)。我在以下代码段中使用了更简单的速记方法(animation:slideIn 1s;)。

.section-enter-active {
  animation: slideIn 1s;
}
.section-leave-active {
  animation: slideOut 1s;
}

@keyframes slideIn {
  from {
    top: 100vh;
  }
  to {
    top: 0;
  }
}
@keyframes slideOut {
  from {
    top: 0;
  }
  to {
    top: -100vh;
  }
}

演示2

优化CSS过渡效果

你还可以通过使用调整动画性能,而不是过渡toptranslateY

/* top initially 0 in .wrapper */

.section-leave-active,
.section-enter-active {
  transition: .5s;
}
.section-enter {
  transform: translateY(100%);
}
.section-leave-to {
  transform: translateY(-100%);
}

{{链接1:示例3}}


-1

使用Mixin

感谢你的解释@tony19
请使用mixin,这样逻辑可以轻松重复使用。
此外,您可以使用reverse将slideIn和slideOut组合在一起:

@mixin animationmixin($type:'animation', $style:'', $duration:1s) {
    
    @keyframes #{$type}-#{$style} { // register animation
        0% { opacity: 1;  transform: none; } // reset style
        100% { @content; } // custom style
    }
    
    .#{$style} { // add '.section'
        &-enter-active, &-leave-active { // add '.section-enter-active', ...
            transition: #{$duration};
        }
        &-enter, &-leave-to {
            animation: #{$type}-#{$style} #{$duration}; // use animation
        }
        &-leave, &-enter-to {
            animation: #{$type}-#{$style} #{$duration} reverse; // use animation in reverse 
        }
    }
}

使用方法如下:

@include animationmixin($style:'section') { // set custom styling
    transform: translateY(100%);
};

就像这样:

@include animationmixin($style:'fade') {
    opacity: 0;
    transform: scale(0.9);
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接