先看看效果图
核心逻辑
就是用transition组件+css动画
主要有一个问题就是router返回的时候没有参数,返回动画和push动画应该是不一样的,所以这里做了一下处理
先看代码:
app.vue
<template>
<div id="app" :class="[class_name]">
<transition :name="transition_name">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
</transition>
<transition :name="transition_name">
<router-view v-if="!$route.meta.keepAlive" />
</transition>
</div>
</template>
<script type="text/javascript">
export default {
name: "app",
data() {
return {
transition_name:'app-slide-fade',
class_name:'',
};
},
created() {
this.$router.beforeEach((to,from,next)=>{
//判断是否返回
if(from.params.back){
this.class_name = 'app-back';
}else{
this.class_name = '';
}
next();
})
}
};
</script>
<style lang="less">
.app-slide-fade-enter-active {
transition: all .3s ease-out;
}
.app-slide-fade-leave-active {
transition: all .2s ease-out;
}
.app-slide-fade-enter{
transform: translateX(100%) scale(.8);
opacity: 0;
}
.app-slide-fade-enter-to{
transform: translate(0) scale(1);
opacity: 1;
position: absolute;
z-index: 1;
top:0;
}
.app-slide-fade-leave-to{
transform: translateX(-10%) scale(.9);
opacity: .5;
}
.app-back{
.app-slide-fade-enter{
transform: translateX(-100%) scale(.9);
opacity: 0;
}
.app-slide-fade-enter-to{
transform: translate(0) scale(1);
opacity: 1;
}
.app-slide-fade-leave-to{
transform: translateX(10%) scale(.9);
}
}
</style>
init.js
const originalGo = router.go.bind(router);
window.addEventListener('popstate',()=>{
router.app.$route.params.back = true;
})
//初始化的时候修改 route的参数,就是beforeEach里面的back
router.go = num => {
router.app.$route.params.back = true;
return originalGo(num);
};
说明
主要是修改了router的go函数,增加了$route.params.back = true ,就是beforeEach里面的from
同时监听popstate事件,处理手机返回按钮
app.vue的代码比较简单,因为使用了keep-alive,所以需要2个transition