Transitions

With Vue.js’ transition system you can apply automatic transition effects when elements are inserted into or removed from the DOM. There are two options to do so: defining CSS classes with transitions/animations, or by registering a definition object containing custom JavaScript hook functions.

With the directive v-transition="my-transition" applied, Vue will:

  1. Try to find a JavaScript transtion definition registered either through Vue.transition(id, def) or passed in with the transitions option, with the id "my-transition". If it finds it, it will use that definition object to perform the custom JavaScript based transition.

  2. If no custom JavaScript transition is found, it will automatically sniff whether the target element has CSS transitions or CSS animations applied, and add/remove the CSS classes at the appropriate times.

  3. If no transitions/animations are detected, the DOM manipulation is executed on next frame.

All Vue.js transitions are triggered only if the DOM manipulation was applied by Vue.js, either through built-in directives, e.g. v-if, or through Vue instance methods, e.g. vm.$appendTo().

CSS Transitions

A typical CSS transition looks like this:

1
<p class="msg" v-if="show" v-transition="expand">Hello!</p>

You also need to define CSS rules for .expand-enter and .expand-leave classes:

1
2
3
4
5
6
7
8
9
10
11
12
.msg {
transition: all .3s ease;
height: 30px;
padding: 10px;
background-color: #eee;
overflow: hidden;
}

.msg.expand-enter, .msg.expand-leave {
height: 0;
padding: 0 10px;
opacity: 0;
}

Hello!

The classes being toggled are based on the value of your v-transition directive. In the case of v-transition="fade", the classes being toggled will be .fade-enter and .fade-leave. When no value is provided they will default to .v-enter and .v-leave.

When the show property changes, Vue.js will insert or remove the <p> element accordingly, and apply transition classes as specified below:

When multiple elements are being transitioned together, Vue.js batches them and only applies one forced layout.

CSS Animations

CSS animations are applied in the same way with CSS transitions, the difference being that v-enter is not removed immediately after the element is inserted, but on an animationend callback.

Example: (omitting prefixed CSS rules here)

1
<p class="animated" v-if="show" v-transition="bounce">Look at me!</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.animated {
display: inline-block;
}

.animated.bounce-enter {
animation: bounce-in .5s;
}

.animated.bounce-leave {
animation: bounce-out .5s;
}

@keyframes bounce-in {
0% {
transform: scale(0);
}

50% {
transform: scale(1.5);
}

100% {
transform: scale(1);
}

}
@keyframes bounce-out {
0% {
transform: scale(1);
}

50% {
transform: scale(1.5);
}

100% {
transform: scale(0);
}

}
Look at me!

JavaScript Functions

The following example registers a custom JavaScript transition definition using jQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Vue.transition('fade', {
beforeEnter: function (el) {
// a synchronous function called right before the
// element is inserted into the document.
// you can do some pre-styling here to avoid
// FOC (flash of content).
},
enter: function (el, done) {
// element is already inserted into the DOM
// call done when animation finishes.
$(el)
.css('opacity', 0)
.animate({ opacity: 1 }, 1000, done)
// optionally return a "cancel" function
// to clean up if the animation is cancelled
return function () {
$(el).stop()
}
},
leave: function (el, done) {
// same as enter
$(el).animate({ opacity: 0 }, 1000, done)
return function () {
$(el).stop()
}
}
})

All of the above hook functions are called with their this contexts set to the associated Vue instances. If the element is the root node of a Vue instance, that instance will be used as the context. Otherwise, the context will be the owner instance of the transition directive.

Then you can use it by providing the transition id to v-transition. Note this has higher priority than CSS transitions.

1
<p v-transition="fade"></p>

Next: Building Larger Apps.