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'
    }
  }
})