0

Is there any way to manually or programmatically trigger an enter or leave transition in vue.js?

From reading the documentation it seems that transitions only ever trigger for v-if and v-show.

However, my use-case is to animate the movement of an element from one position to another on one user event, and move it back on a second user event.

The animations themselves are easy to achieve using Velocity, but I am having issues triggering them when required.

I don't want to change the visibility or presence of the element, so switching v-show and v-if to start the transition is out of the question.

I have tried using a key on the element, but this is basically the same as creating and destroying it, causing both enter and leave transitions (move and move back) to fire sequentially.

Is there any way to manually trigger an enter transition, then subsequently trigger the leave transition, while preserving the visibility of the element itself?

For illustration here is a codepen with the move animations set up for enter and leave.

<div id="app">
  <transition 
    name="move"
    @enter="enter"           
    @leave="leave"
    @after-enter="afterEnter"              
    @after-leave="afterLeave"              
  >
    <div 
      id="moveMe"
      @click="itemClick"
      :key="itemKey">
    </div>
  </transition>
</div>
var app = new Vue({
  el: "#app",
  data: {
    itemKey: 0
  },
  methods: {
    itemClick() {
      this.itemKey++
    },
    enter(el, done) {
      Velocity(el, { left: '200px'}, {
          duration: 500,
          complete: function() {
            done()
          }
        })  
    },
    afterEnter(el) {
      el.style.left = "200px"
    },
    leave(el, done) {
      Velocity(el, { left: '0px'}, {
          duration: 500,
          complete: function() {
            done()
          }
        })  
    },
    afterLeave(el) {
      el.style.left = "0px"
    }
  }
})

What I am trying to achieve is to trigger the enter (move right) animation on click of the element, and then trigger the leave (move left) animation on second click of the element.

2
  • Please show us some code, there are plenty of unknown variables in your question 1. What is Velocity? 2. What key on the element have you tried? I dont think that there is way to trigger transition while preserving the visibility of the element Commented Nov 25, 2019 at 11:26
  • I have added a codepen illustrating my problem. Velocity is a JavaScript animation library. It is referenced from the vue docs when giving examples of JavaScript animations. Commented Nov 25, 2019 at 13:55

1 Answer 1

1

From researching this quite a bit, it seems that it is not possible to trigger transitions manually.

Transitions only seem to work on create/destroy, or with v-show.

To achieve what I want, I have just had to explicitly call the animation library without wrapping the animated element in a transition tag as shown in this codepen example.

<div id="app">
  <div 
     id="moveMe"
     @click="itemClick">
  </div>
</div>
var app = new Vue({
  el: "#app",
  data: {
    moved: false
  },
  methods: {
    itemClick() {
      let el = this.$el.querySelector('#moveMe')
      if(this.moved) {        
        this.moveLeft(el)
      } else {
        this.moveRight(el)
      }
      this.moved = !this.moved
    },
    moveRight(el) {
      Velocity(el, { 
        left: '200px'
      }, 
      {
        duration: 500
      })  
    },
    moveLeft(el) {
      Velocity(el, { 
        left: '0px'
      },
      {
        duration: 500
      })  
    }
  }
})

I cant validate how effective this solution will be, as I imagine this may leave the DOM and the Virtual DOM out of whack, depending on what you are trying to achieve.

I will leave this question open in case anyone else has a better solution then this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.