<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
<div id="app" :style="appStyle">
<transition name="route-change">
<router-view class="route"></router-view>
</transition>
</div>
const router = new VueRouter({
routes: [
[ '/', 'home', 'black' ],
[ '/xxx', 'hello, world!!', 'red' ],
[ '/yyy', 'fuck the world', 'green' ],
[ '/zzz', 'fuck everything', 'blue' ],
].map(([ path, text, color ]) => ({
path,
component: {
template: `<div style="background: ${color};">${text}</div>`,
},
})),
});
new Vue({
router,
el: '#app',
data: () => ({
routeIndex: 0,
}),
computed: {
appStyle() {
return {
height: `${100 * (this.$router.options.routes.length + 1)}vh`,
};
},
},
watch: {
routeIndex(val) {
const { $router } = this;
const { routes } = $router.options;
const index = Math.max(0, Math.min(routes.length - 1, val | 0));
$router.push(routes[index].path);
},
},
mounted() {
const onScroll = () => this.routeIndex = window.scrollY / window.innerHeight | 0;
onScroll();
window.addEventListener('scroll', onScroll);
},
});
html, body {
margin: 0;
}
.route {
width: 100vw;
height: 100vh;
position: fixed;
display: flex;
justify-content: center;
align-items: center;
color: white;
font: bold 64px monospace;
transition: transform 0.2s ease-in;
}
.route-change-enter {
transform: translateX(100%);
}
.route-change-enter-to,
.route-change-leave {
transform: translateX(0);
}
.route-change-leave-to {
transform: translateX(-100%);
}