Dalaigh88
Dalaigh88

Reputation: 427

Event Driven Transitions in Vue.js

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.

Upvotes: 0

Views: 1733

Answers (1)

Dalaigh88
Dalaigh88

Reputation: 427

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.

Upvotes: 1

Related Questions