看了不少网上路由转场方案,大多是在路由的meta配置里,增加index参数,然后通过watch监听路由变化,对比index大小进行判断是左滑还是右滑操作,但是并不能达到像移动端原生的那种效果。
经过查找,可以重写router的push、replace等方法,效果更好,示例如下:
1、还是一样,路由配置里,meta属性增加isFront字段,判断路由状态
profile: {
path: '/profile',
name: 'Profile',
component: Profile,
meta: {
keepAlive: true,
isFront: false,
}
},
2、重写router的push、replace方法,主要是修改当前路由状态,和即将更换的路由状态
// 保存原来的push函数
const routerPush = VueRouter.prototype.push
const routerReplace = VueRouter.prototype.replace
// 重写push函数
VueRouter.prototype.push = function push(location) {
operateRouteLocation(location , false);
return routerPush.call(this, location).catch(error => error)
}
// 重写replace函数
VueRouter.prototype.replace = function replace(location) {
operateRouteLocation(location, true);
return routerReplace.call(this, location).catch(error => error)
}
// 修改路由配置数据,一般push需要动画,replace不需要动画
function operateRouteLocation(location, isReplace){
let path = null;
let name = null;
if(typeof(location)==="string"){
if(location.indexOf("/") != -1){
path = location;
}
else {
name = location
}
}
else {
if(location.path != null) {
path = location.path;
}
else {
name = location.name;
}
}
const routesTemp = routes.filter((element) => {
if(path != null){
return element.path === path
}
else {
return element.name === name
}
});
// 在这里获取数据
if(routesTemp != null && routesTemp.length>0){
const first = routesTemp[0];
if(isReplace){
first.meta.isFront = false
router.currentRoute.meta.isFront = false;
}
else {
first.meta.isFront = true
router.currentRoute.meta.isFront = false;
}
}
}
3、watch监听路由跳转,设置动画,
watch: {
//使用watch 监听$router的变化
$route(to, from) {
// 有主级到次级
if (from.meta.isFront) {
this.transitionName = "slide-right";
// console.log('向左滑动,推出下一级');
} else if (to.meta.isFront) {
// // 由次级到主级
// console.log('向右滑动,返回上一级');
this.transitionName = "slide-left"; // 向左滑动
} else {
this.transitionName = ""; //无过渡效果
}
},
},
然后
<transition :name="transitionName">
<router-view >
</router-view>
</transition>
4、动画样式
.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
will-change: transform;
transition: all 0.5s;
width: 100vw;
position: absolute;
}
/* 推出下一页 */
.slide-right-leave-active {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.slide-left-enter {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
/* 返回上一页 */
.slide-left-leave-active {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.slide-right-enter {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
以上是大致思路,不足之处,欢迎讨论
网友评论