Transitions in Vue.js are really great. There is no doubt that they can bring your app to life very easily but often you have to write them from scratch in each project or even bring some CSS library like animate.css to make them look good.
What if we could encapsulate these into components and simply reuse them across several projects ? We will look at several ways to define transitions and dig our way to make them really reusable.
Note: this article was originally posted here on the Vue.js Developers blog on 2018/02/05
Raw transition component and CSS
The easiest way do define a transition is using the transition or transition-group components. This requires defining a name and some CSS for the transition.
Seems easy right ? However, there is a problem with this approach. We can’t really reuse this transition in another project.
Encapsulated transition component
What if we encapsulate the previous logic into a component and use it as a component instead ?
By providing a slot in our transition component we could use it almost in the same way as a basic transition component. This is slightly better than the previous example but what if we want to pass other transition specific props such as mode or maybe even some hooks ?
Encapsulated wrapper transition component
Fortunately there is a feature in Vue that allows us passing whatever extra props and listeners the user specifies to our internal tags/component. If you didn’t know yet, you can access extra passed props via $attrs and use them in combination with v-bind to bind them as props. The same applies to events via $listeners and apply them with v-on
Now we can pass any events and props that a normal transition component would accept which makes our component even more reusable but why not taking it a step further and add the possibility to customize the duration easily via a prop.
Explicit duration prop
Vue provides a duration prop for the transition component, however it’s intended for more complex chained animations and it helps Vue chaining them together correctly.
What we really need in our case, is to control the css animation/transition via a component prop. We could achieve this by not specifying the explicit css animation duration in our css but rather apply it as a style. We can do that with the help of transition hooks which are pretty similar to component lifecycle hooks but they are called before and after transitioning the desired element. Let’s see how that looks in action.
Now we have control over the real visible transition duration which makes our reusable transition flexible and easy to use. But what about transitioning multiple elements such as list items ?
Transition group support
The most straight forward way that you think of would probably be to create a new component, let’s say fade-transition-group and replace the current transition tag with the transition-group one to achieve a group transition. What if we could do that in the same component and expose a group prop which will switch to a transition-group implementation ? Fortunately we can do that either with render functions or with the help of component and is attribute.
There is one caveat with transition-group elements which is presented in the documentation. We basically have to set the position of each item to absolute when the element is leaving to achieve a smooth moving animation of the other items. We also have to add a move-class and manually specify the transition duration since there is no javascript hook for move Let’s add these tweaks to our previous example.
With a few more adjustments and by extracting our javascript logic in a mixin, we can apply it to easily create new transition components which we could simply drop in and use them in our next project.
Vue Transitions
Everything described until here is basically what this small Transition Collection contains. It has 10 encapsulated transition components at ~1kb (minified) each. I think it’s pretty handy and can be used with ease across different projects. Feel free to give it a try :)
Conclusion
We started from a basic transition example and managed to create reusable transition components in the end with adjustable duration and transition-group support. You can use these tips to create your own transition components based on your needs or who knows, maybe contribute to Vue Transitions and add more transitions there. Hopefully you learned something from this article and it will help you build beautiful transitions.