1

When I tried to add class to an element in the mounted lifecycle, the transition effect is not working. The element immediately appeared as the final state:

However, if I use setTimeout to delay the class change, the transition will be working.

new Vue({
  el: '#example-1',
  mounted: function () { 
     // setTimeout(function () {
      let test = document.getElementsByClassName('test')[0]
      test.classList.add('loaded')
     // }, 0) 
  }
})
.test {
  color:red;
  font-size:60px;
  transform:none;
  transition: all 1s linear;
}

.test.loaded {
  transform: translateX(400px)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>


<div id="example-1">
  <h1 class='test'>
    fa
  </h1>
</div>

I understand why this is happening if it's in vanilla js: Transition needs to happen from one rendered state to another. The delay is there to allow the initial element to be rendered first.(Refer to this SO post)

However in Vue, I thought that Mounted already means that the initial view has been rendered. So there is already an initial rendered state.

It seems that's not true from this example.

So is mounted !== rendered?

4
  • Mounted is when the real DOM is replaced with the new virtual DOM. It wont work for what you are wanting. Commented Feb 7, 2018 at 8:29
  • @skribe Why is that? If mounted means real Dom is replaced with the virtual DOM, then before I even modified the class of the element in mounted, there should already be an initial rendered element in the real DOM already Commented Feb 7, 2018 at 8:34
  • I am certain about all the underpinnings of how it works, I just know I have tried similar things and it has failed. The DOM is rendered then mounted. Have a look here for another way to do what you seem to be trying to do. stackoverflow.com/questions/40618894/… Commented Feb 7, 2018 at 8:48
  • @strike using the transition component is a good way. However I am still trying figure out why. I have also tried with class binding and did:this.loaded = true to change stage and thus trigger class change in mounted. Still not working. Commented Feb 7, 2018 at 9:26

1 Answer 1

1

If you add the class right after the element being added to the DOM, the browser will not be able to trigger a CSS transition because when the browser checks the transform it also checks what transform was being applied before, which turns out to be none, therefore it skips the transition. That's why you need some setTimeout or requestAnimationFrame to make it work. Here's a demo with no Vue 🙂

const a = document.createElement('div')
a.textContent = 'fa'
a.classList.add('test')
document.body.appendChild(a)
a.classList.add('loaded')
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.