vue输入过渡无法正常工作

时间:2019-01-18 19:27:45

标签: javascript css animation vue.js vuejs2

我正在一个项目中,我必须使用输入和离开动画渲染一些组件,当一个组件进入屏幕时,它必须从底部进入,而当它离开时,它必须向上移动,期望的行为是,当我更改component标签的: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>

但是实际行为是第一个组件向上,但是第二个组件在没有动画的情况下立即出现。

如果我一次渲染一个(不破坏一个并以相同的动作渲染另一个),则一切正常。我不知道发生了什么。

2 个答案:

答案 0 :(得分:1)

您的CSS中有一些问题。

CSS过渡和CSS动画

可以使用 CSS Transitions CSS Animations来实现过渡。在这种情况下,您的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过渡正常工作。

demo 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;
  }
}

demo 2

优化CSS过渡

您也可以使用tweak your animation performancetranslateY,而不用转换top

/* top initially 0 in .wrapper */

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

demo 3

答案 1 :(得分:0)

使用 Mixin

感谢您的解释@tony19
请为此使用mixin,以便可以轻松重复逻辑。
此外,您可以使用 reverse 组合滑入和滑出:

@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);
};