问题描述:移动端页面切换往往需要左滑、右滑的过渡效果。
Vue Router的官网也有相关过渡动效的介绍。以下为官网的例子。
<!-- 使用动态的 transition name -->
<transition :name="transitionName">
<router-view></router-view>
</transition>
// 接着在父组件内
// watch $route 决定使用哪种过渡
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
具体代码 移步这里
这种实现方式并不是我需要的。因为我的路由跳转可能并不都是父子关系。我接着看官方文档,刚好看到有一个叫 滚动行为 的介绍。这是一个在创建Router实例时提供的方法--scrollBehavior 。该方法原本是用来记录路由滚动位置的,但我觉得它刚好可以来帮我判断路由是在前进还是后退。
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
}
})
这个方法返回滚动位置的对象信息,长这样:
{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }} //(offset 只在 2.6.0+ 支持)
按照官网的意思,当页面返回时,第三个参数savedPosition会记录上一个页面的滚动位置的对象信息。而当页面前进时,savedPosition则会返回一个null。这就刚好可以为我所用了。既如果 savedPosition 为空,我们认为页面是在前进,否则认为是在后退。我们可以通过管理一个Vuex的全局变量,来表示页面的前进、后退情况。
const router = new VueRouter({
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
store.commit('PageForward');
return savedPosition
} else {
store.commit('pageBack');
return { x: 0, y: 0 }
}
}
});
vuex代码:
state: {
isBack:false
},
mutations: {
pageBack(state){
state.isBack = true
},
PageForward(state){
state.isBack = false
}
},
App.vue代码:
<transition :name="transitionName">
<router-view v-if="!$route.meta.keepAlive" />
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
</transition>
js:
computed: {
transitionName() {
return this.$store.state.isBack?'slide-right':'slide-left'
}
},
ps.由于官网并未提及 scrollBehavior的此种用途,网上我也没见过这种用法,所以可能会存在一定问题,欢迎指出