最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - vue enter transition not working properly - Stack Overflow

programmeradmin7浏览0评论

i'm working on a project where i have to render some ponents with an enter and leave animation, when a ponent enters the screen it has to enter form the bottom, and when it leaves, it has to do it going upwards, the desired behavior is that when i change the :is property of the ponent tag, the current ponent goes upwards and the next one es from the bottom, the code looks like this:

<template>
  <div class="home">
    <transition name="section">
      <ponent :is="activeSection"></ponent>
    </transition>
  </div>
</template>

<script>
import p1 from './p1';
import p2 from './p2';

export default {
  ponents: {
    p1,
    p2
  },
  data() {
    activeSection: 'p1'
  }
</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>

but the actual behavior is that the first ponent goes upwards but the second appears inmediatly after without animation.

if i render one at a time (not destructing one and rendering another with the same action) everything works perfectly. I dont know what is happening.

i'm working on a project where i have to render some ponents with an enter and leave animation, when a ponent enters the screen it has to enter form the bottom, and when it leaves, it has to do it going upwards, the desired behavior is that when i change the :is property of the ponent tag, the current ponent goes upwards and the next one es from the bottom, the code looks like this:

<template>
  <div class="home">
    <transition name="section">
      <ponent :is="activeSection"></ponent>
    </transition>
  </div>
</template>

<script>
import p1 from './p1';
import p2 from './p2';

export default {
  ponents: {
    p1,
    p2
  },
  data() {
    activeSection: 'p1'
  }
</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>

but the actual behavior is that the first ponent goes upwards but the second appears inmediatly after without animation.

if i render one at a time (not destructing one and rendering another with the same action) everything works perfectly. I dont know what is happening.

Share Improve this question edited Jan 20, 2019 at 18:53 tony19 139k23 gold badges277 silver badges347 bronze badges asked Jan 18, 2019 at 19:27 Carlos PisarelloCarlos Pisarello 1,2846 gold badges23 silver badges41 bronze badges 2
  • 1 could you please put this somewhere like codesandbox so its easier to recreate and look into? – Gowri Commented Jan 19, 2019 at 1:40
  • Hey, in my case, I just had to add an appear attribute to my transition. Hope it may help the others having this issue! – l-portet Commented Sep 10, 2021 at 19:21
Add a ment  | 

2 Answers 2

Reset to default 5

There are a few problems in your CSS.

CSS Transitions and CSS Animations

A transition can be implemented using either CSS Transitions or CSS Animations. Your CSS incorrectly mixes the two concepts in this case.

In particular, the slideIn keyframes and .section-enter/.section-enter-to rules are effectively performing the same task of moving .section into view. However, this is missing a transition rule with a non-zero time, required to animate the change, so the change occurs immediately. The same issue exists for the slideOut keyframes and leave rules.

.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 */
}

Removing the keyframes, and adding the missing rules (as shown above) would result in a working CSS Transition.

demo 1

Using CSS Animations

Alternatively, you could use keyframes with CSS Animations, where the animation is applied only by the *-active rules, and no *-enter/*-leave rules are used. Note your question contained unnecessary quotes in animation-name: 'slideIn';, which is invalid syntax and would be silently ignored (no animation occurs). I use a simpler shorthand in the following snippet (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

Optimizing CSS Transitions

You could also tweak your animation performance by using translateY instead of transitioning 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

Use a Mixin

Thanks for the explanation @tony19
please use a mixin for this so the logic can be repeated easily.
Also, your slideIn and slideOut can be bined by using 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 
        }
    }
}

Use it like this:

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

And like this:

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

评论列表(0)

  1. 暂无评论