一、目标
实现原生app页面切换动画。前进左滑后退右滑,同级tab切换无动画
二、分析
1、如何判断页面是前进还是后退?
2、如何在前进后退时使用不同的动画?
三、思路
1、为每个页面定义一个变量来表示当前所在的层级(比如:A -> B -> C ,A的层级为1,B的层级为2,C的层级为3)
2、在页面每次切换时判断当前显示的页面和即将显示的页面的层级关系,即可知道是前进还是后退(例如: A -> B,判断A页面与B页面层级关系,如果A页面层级小于B页面则为前进,反之为后退)。
3、利用vue导航守卫判断层级关系,动态的改变路由动画,(即改变变量transform,transform为一个全局变量,见代码)
四、实现
路由文件,自定义tree为当前页面的层级
ps:目前不能使用keep-avail标签缓存,会导致动画效果不对
const routers=[
{
path: '/test',
name: 'test', //财务查询页
component: resolve => require(['@/page/test/test'], resolve),
meta:{
title : '测试页', // 标题设置在这里
tree: 4,
}
},
{
path: '/list1',
name: 'list1', //财务查询页
component: resolve => require(['@/page/test/list1'], resolve),
meta:{
title : '测试页', // 标题设置在这里
tree: 1,
}
},
{
path: '/list2',
name: 'list2', //财务查询页
component: resolve => require(['@/page/test/list2'], resolve),
meta:{
title : '测试页', // 标题设置在这里
tree: 2,
}
},
{
path: '/list3',
name: 'list3', //财务查询页
component: resolve => require(['@/page/test/list3'], resolve),
meta:{
title : '测试页', // 标题设置在这里
tree: 3,
}
},
]
export default routers;
导航守卫
//路由跳转前进后退动画,Vue原型上定义transition为动画效果
router.beforeEach ( (to, from, next) => {
Vue.prototype.transition = 'slide-none';
if(from.meta.tree > to.meta.tree) {
// 后退,想右滑动
Vue.prototype.transition = 'slide-right';
from.meta.keepAlive = false;
to.meta.keepAlive = true;
} else if(from.meta.tree < to.meta.tree) {
// 前进,想左滑动
Vue.prototype.transition = 'slide-left';
from.meta.keepAlive = true;
to.meta.keepAlive = false;
}else {
// 同一层级,无动画
Vue.prototype.transition = 'slide-none';
from.meta.keepAlive = true;
to.meta.keepAlive = true;
}
next();
})
app.vue模板标签
css动画样式
/*向左滑动*/
@keyframes slideInLeft {
from {
transform: translate3d(100%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
to {
transform: translate3d(0, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translate3d(0%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
to {
transform: translate3d(-100%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
}
.slide-left-enter-active{
position: fixed;
top: 0;
left: 0%;
width: 100vw;
height: 100vh;
animation: slideInLeft 1s linear forwards;
}
.slide-left-leave-active{
position: fixed;
top: 0;
left: 0%;
width: 100vw;
height: 100vh;
animation: slideInRight 1s linear forwards;
}
/*向右滑动*/
@keyframes slideOutLeft {
from {
transform: translate3d(-100%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
to {
transform: translate3d(0%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
}
@keyframes slideOutRight {
from {
transform: translate3d(0%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
to {
transform: translate3d(100%, 0, 0);
position: fixed;
top: 0;
left: 0;
opacity: 1;
}
}
.slide-right-enter-active{
position: fixed;
top: 0;
left: 0%;
width: 100vw;
height: 100vh;
animation: slideOutLeft 1s linear forwards;
}
.slide-right-leave-active{
position: fixed;
top: 0;
left: 0%;
width: 100vw;
height: 100vh;
animation: slideOutRight 1s linear forwards;
}
上一篇 : Vue SPA 实现类似App前进刷新后退不刷新
下一篇:在github上在线演示项目