admin管理员组

文章数量:1022997

I am using Vue 2 and attempting to include CSS animations on elements that are created and destroyed frequently. Below is an example of my code:

  export default {
    name: 'MyElement',
    methods: {
      enterStart: function (el) {
        console.log('about to enter');
        el.classList.add('testing-enter');
      },
      enter: function (el) {
        console.log('entered');
      },
      leaveStart: function (el) {
        console.log('starting to leave!');
      },
      leave: function (el) {
        console.log('leaving!');
      },
    }
  };
.testing-enter {
  animation: enter .2s;
}

.testing-leave {
  animation: leave .2s;
}

@keyframes enter {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes leave {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0);
  }
}
<template>
  <div>
    <transition
      @before-enter="enterStart"
      @enter="enter"
      @leave="leaveStart"
      @leave-active="leave"
      appear
    >
      <div>My element is here!</div>
    </transition>
  </div>
</template>

I am using Vue 2 and attempting to include CSS animations on elements that are created and destroyed frequently. Below is an example of my code:

  export default {
    name: 'MyElement',
    methods: {
      enterStart: function (el) {
        console.log('about to enter');
        el.classList.add('testing-enter');
      },
      enter: function (el) {
        console.log('entered');
      },
      leaveStart: function (el) {
        console.log('starting to leave!');
      },
      leave: function (el) {
        console.log('leaving!');
      },
    }
  };
.testing-enter {
  animation: enter .2s;
}

.testing-leave {
  animation: leave .2s;
}

@keyframes enter {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes leave {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0);
  }
}
<template>
  <div>
    <transition
      @before-enter="enterStart"
      @enter="enter"
      @leave="leaveStart"
      @leave-active="leave"
      appear
    >
      <div>My element is here!</div>
    </transition>
  </div>
</template>

First off, none of this works unless I include appear in my <transition ...> element. I know that this makes the transition happen on initial rendering, but I want them to happen any time the element is created or destroyed.

Next, in my console. I can see enterStart and enter both run, but leaveStart and leave never run, even when the elements are destroyed. What am I doing wrong?

Share Improve this question asked Mar 15, 2017 at 21:37 ZachZach 5,12111 gold badges34 silver badges54 bronze badges 2
  • i've just created this codepen for test link – Marcelo H. Carneiro Commented Mar 15, 2017 at 22:13
  • @marceloch2 thank you! – Zach Commented Mar 16, 2017 at 14:49
Add a ment  | 

2 Answers 2

Reset to default 2

The element inside the transition needs a state (show or hide). Also your transition needs a name that must much the transition in the CSS and it should be named with

name="transitionName"

e.g:

new Vue({
  el: "#app",
  data: function() {
    return {
      showThisElement: false
    }
  },
  methods: {
    toggleShow: function() {
      this.showThisElement = !this.showThisElement
    }
  }
});
    .testing-enter-active {
      animation: enter .2s;
    }

    .testing-leave-active {
      animation: leave .2s;
    }

    @keyframes enter {
      0% {
        opacity: 0;
        transform: scale(0);
      }
      100% {
        opacity: 1;
        transform: scale(1);
      }
    }
    @keyframes leave {
      0% {
        opacity: 1;
        transform: scale(1);
      }
      100% {
        opacity: 0;
        transform: scale(0);
      }
    }
   <div id="app">
  
  <div @click="toggleShow">Show/Hide</div>
  
  <transition 
    name="testing">

    <div v-if="showThisElement">My element is here!</div>

  </transition>
</div>

In the codepen, click on 'show/hide' to toggle the transition.

http://codepen.io/anon/pen/WpZPJp

Problem solved!

So I took out the transition from the individual ponent and created a transition-group instead around the container ponent that rendered them.

Then, after a bit more reading I realized I wanted to add the mode="out-in" field to my transition-group so that the leaving ponents fully animate before the new ones are rendered.

I also looked at the HTML when the animations were supposed to be happening to see what classes Vue added. It looks like Vue added v-enter-active, v-enter-to, and v-leave-to. Instead of customizing any names I just stuck with those classes and added my animations to them in the styling.

Hopefully if anybody else wants a similar effect this helps them decrease their stress levels a bit...

I am using Vue 2 and attempting to include CSS animations on elements that are created and destroyed frequently. Below is an example of my code:

  export default {
    name: 'MyElement',
    methods: {
      enterStart: function (el) {
        console.log('about to enter');
        el.classList.add('testing-enter');
      },
      enter: function (el) {
        console.log('entered');
      },
      leaveStart: function (el) {
        console.log('starting to leave!');
      },
      leave: function (el) {
        console.log('leaving!');
      },
    }
  };
.testing-enter {
  animation: enter .2s;
}

.testing-leave {
  animation: leave .2s;
}

@keyframes enter {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes leave {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0);
  }
}
<template>
  <div>
    <transition
      @before-enter="enterStart"
      @enter="enter"
      @leave="leaveStart"
      @leave-active="leave"
      appear
    >
      <div>My element is here!</div>
    </transition>
  </div>
</template>

I am using Vue 2 and attempting to include CSS animations on elements that are created and destroyed frequently. Below is an example of my code:

  export default {
    name: 'MyElement',
    methods: {
      enterStart: function (el) {
        console.log('about to enter');
        el.classList.add('testing-enter');
      },
      enter: function (el) {
        console.log('entered');
      },
      leaveStart: function (el) {
        console.log('starting to leave!');
      },
      leave: function (el) {
        console.log('leaving!');
      },
    }
  };
.testing-enter {
  animation: enter .2s;
}

.testing-leave {
  animation: leave .2s;
}

@keyframes enter {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes leave {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0);
  }
}
<template>
  <div>
    <transition
      @before-enter="enterStart"
      @enter="enter"
      @leave="leaveStart"
      @leave-active="leave"
      appear
    >
      <div>My element is here!</div>
    </transition>
  </div>
</template>

First off, none of this works unless I include appear in my <transition ...> element. I know that this makes the transition happen on initial rendering, but I want them to happen any time the element is created or destroyed.

Next, in my console. I can see enterStart and enter both run, but leaveStart and leave never run, even when the elements are destroyed. What am I doing wrong?

Share Improve this question asked Mar 15, 2017 at 21:37 ZachZach 5,12111 gold badges34 silver badges54 bronze badges 2
  • i've just created this codepen for test link – Marcelo H. Carneiro Commented Mar 15, 2017 at 22:13
  • @marceloch2 thank you! – Zach Commented Mar 16, 2017 at 14:49
Add a ment  | 

2 Answers 2

Reset to default 2

The element inside the transition needs a state (show or hide). Also your transition needs a name that must much the transition in the CSS and it should be named with

name="transitionName"

e.g:

new Vue({
  el: "#app",
  data: function() {
    return {
      showThisElement: false
    }
  },
  methods: {
    toggleShow: function() {
      this.showThisElement = !this.showThisElement
    }
  }
});
    .testing-enter-active {
      animation: enter .2s;
    }

    .testing-leave-active {
      animation: leave .2s;
    }

    @keyframes enter {
      0% {
        opacity: 0;
        transform: scale(0);
      }
      100% {
        opacity: 1;
        transform: scale(1);
      }
    }
    @keyframes leave {
      0% {
        opacity: 1;
        transform: scale(1);
      }
      100% {
        opacity: 0;
        transform: scale(0);
      }
    }
   <div id="app">
  
  <div @click="toggleShow">Show/Hide</div>
  
  <transition 
    name="testing">

    <div v-if="showThisElement">My element is here!</div>

  </transition>
</div>

In the codepen, click on 'show/hide' to toggle the transition.

http://codepen.io/anon/pen/WpZPJp

Problem solved!

So I took out the transition from the individual ponent and created a transition-group instead around the container ponent that rendered them.

Then, after a bit more reading I realized I wanted to add the mode="out-in" field to my transition-group so that the leaving ponents fully animate before the new ones are rendered.

I also looked at the HTML when the animations were supposed to be happening to see what classes Vue added. It looks like Vue added v-enter-active, v-enter-to, and v-leave-to. Instead of customizing any names I just stuck with those classes and added my animations to them in the styling.

Hopefully if anybody else wants a similar effect this helps them decrease their stress levels a bit...

本文标签: javascriptVuejs animations not working correctlyStack Overflow