vue-router route stack demo
different transition for route backword and forward, make use of vue-router's abstract mode
by Rocka
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<div id="app">
<button @click="back">back</button>
<div class="view">
<transition :name="transitionName">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
</div>
</div>
CSS
.tan { background-color: tan }
.blue { background-color: dodgerblue }
.pink { background-color: lightpink }
.green { background-color: limegreen }
.view {
position: relative;
width: 200px;
height: 100px;
border: 1px solid black;
}
.page {
position: absolute;
width: 100%;
height: 100%;
}
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
transition-duration: 0.5s;
transition-property: transform, opacity;
}
.slide-left-enter,
.slide-right-leave-active {
opacity: 0;
transform: translate(2em, 0);
}
.slide-left-leave-active,
.slide-right-enter {
opacity: 0;
transform: translate(-2em, 0);
}
Vue
Vue.use(VueRouter);
const Search = Vue.component('search', {
template: `
<div class="page tan">
<p>search results</p>
<router-link to="/playlist/233">233. playlist</router-link>
</div>`
})
const Playlist = Vue.component('playlist', {
template: `
<div class="page blue">
<p>playlist #{{$route.params.id}}</p>
<router-link to="/artist/234">234. artist</router-link>
</div>`
})
const Artist = Vue.component('artist', {
template: `
<div class="page pink">
<p>artist #{{$route.params.id}}</p>
<router-link to="/album/235">235. album</router-link>
</div>`
})
const Album = Vue.component('album', {
template: `
<div class="page green">
<p>album #{{$route.params.id}}</p
</div>`
})
new Vue({
el: "#app",
router: new VueRouter({
routes: [
{ path: '/', redirect: '/search' },
{ path: '/search', component: Search },
{ path: '/playlist/:id', component: Playlist },
{ path: '/artist/:id', component: Artist },
{ path: '/album/:id', component: Album },
]
}),
methods: {
back() { this.$router.back() }
},
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
})