vue transitions
21 June 2017To fade between pages in vue-router is pretty simple. The transition
component can be used to wrap the router-view
component. But there's a slight issue. If we use it as in the example, the page transitions look a little janky:
<transition name="fade">
<router-view></router-view>
</transition>
CSS:
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-to {
opacity: 0
}
This is because the default behaviour when transitioning between two elements is to perform both transitions simultaneously. This is where transition modes come into play. Using the out-in
mode the first page will completely fade out before the new one fades in:
<transition name="fade" mode="out-in" appear>
Finally, adding the appear
attribute, as above, means that the transition is applied to the first page when it loads (docs).
Issue: the transition is not applied to routes using dynamic route matching. E.g. there is no transition between /post/1
and /post/2
. My guess is that this is because, as the manual says:
when the user navigates from /user/foo to /user/bar, the same component instance will be reused.
The solution (following this StackOverflow answer, thanks!) is to wrap the contents of the page in a div
with a specific key
value (in this example based on the route parameter) and wrap that in the transition
tag:
<transition name="fade" mode="out-in" appear>
<div class="page-contents" :key="$route.params.id">
<!-- component code here -->
</div>
</transition>