前言
在做移动端项目的时候,每次进行push操作,页面都是一闪切到下个界面,整个体验十分H5,尤其是嵌入APP的Hybrid项目,这种体验很容易让用户发觉这是一个H5页面,那我们怎么样才能解决这种突兀的转场呢?
思考
之前用过ionic3
开发过一些项目,为了支持APP的热更新功能
作为UI框架,他们在过场动画方面下足了功夫,让整个APP体验提升了不少
所以我也希望可以在vue项目中加入丝滑的过场动画,来承上启下
刚好Vue官方也提供了专门处理动画的
组件
我们就尝试用该组件来完成页面的转场动画
动画形式主要参考iOS系统push页面时的过渡效果
解决方案
代码样例依赖:
"vue": "^3.0.5",
"vue-router": "^4.0.11"
"vite": "^2.4.4"
1、动画部分解析
A -> B , A在下,B在上,且B左侧增加阴影
A从(0, 0)向左移50%
B从(0, 100%)向左移100%B -> A , A在下,B在上,且B左侧增加阴影
A从(-50%, 0)向右移50%
B从(0, 0)向右移100%整个动画过程是有渐变蒙版,以及动画的贝塞尔曲线,这里忽略蒙版变化,贝塞尔也选择常用的内置
ease-out
2、实现动画内容
- css部分:按照上面分解的内容,可以较容易的实现
这里有几个遇到的坑:
1、页面切换动画执行from页面白屏
因为是文档流的原因,老页面被新页面挤到下面去了,所以使用absolute
让其定位到应该出现的位置
2、阴影设置的问题
需要在初始
状态和active
状态都设置阴影,以避免阴影出现渐变
.slide-right-enter-active,
.slide-left-enter-active,
.slide-right-leave-active,
.slide-left-leave-active {
/* 这里保持动画过程中的阴影 */
box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
will-change: transform;
transition: all 0.5s ease-out;
/* 这里为了解决入栈出栈时的白屏现象 */
position: absolute;
}
.slide-right-enter-from {
/* 这里设置0,为了避免一开始页面内容一闪而过的情况 */
opacity: 0;
transform: translateX(-50%);
}
.slide-right-leave-to {
z-index: 100;
/* 这里为了优化阴影溢出屏幕,不至于突然消失 */
transform: translateX(102%);
}
.slide-right-leave-from {
box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}
.slide-left-enter-from {
z-index: 100;
transform: translateX(100%);
box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}
.slide-left-leave-to {
opacity: 0.4;
transform: translateX(-50%);
}
- 动画设置完成了,接下来需要判断动画触发逻辑,前进还是后退
这里我采用了路由跳转设置params.routeMode
的方式来决定动画形式
const router = useRouter();
router.beforeEach((to, from) => {
const toDepth = to.params.routeMode;
if (toDepth === "push") {
to.meta.transitionName = "slide-left";
} else if (toDepth === "pop") {
to.meta.transitionName = "slide-right";
}
return true;
});
- 最后是模板,路由入口设置动画
结果展示
完整Demo地址:https://github.com/ZTStory/vue_page_transition
在线演示:https://ztstory.github.io/vue_page_transition/#/
ps:如何搭建自己GitHub Pages?看这里
欢迎大家互相学习,喜欢别忘记star哦!