需求描述:当我们从某个特定的页面进入到当前的那个路由页面时,需要滚动浏览器视图到特定内容区域;从其他页面进入当前页面时,则无法滚动视图区域,那么我们如何判断路由跳转呢?
首先我们可能想到的是,路由监听,可以获取 from 和 to 的路由信息。代码如下:
watch:{
$route (to, from) {
console.log(to, from);
}
},
使用上述监听路由时,并没有在控制台打印任何路由信息,而我决定采用深度监听路由变化,代码如下:
watch: {
$route: {
handler: function (val, oldVal){
console.log(val);
},
deep: true // 深度观察监听
}
},
当然使用了深度监听依然没有任何信息输出的,这是我们可以在 watch 中 使用 immediate:true 就可以打印了。
watch: {
'$route':{
handler(newV, oldV){
console.log(newV, oldV)
},
immediate:true
}
},
当然我们也可以使用组件内的钩子函数:beforeRouteEnter 。
注意:beforeRouteEnter 守卫 不能访问 this,因为守卫在单号确认前被调用,因此即将登场的新组件还没被创建。不过你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候,执行回调,并且把组件实例作为回调方法的参数。beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
更多详情,请查看:vue-router 官网之组件内的守卫。
vue-router 路由钩子 beforeRouteEnter 可以用来在初始进入页面前,可以异步获取数据;
beforeRouteEnter (to, from, next) {
next(vm => {
// 因为当钩子执行前,组件实例还没被创建
// vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
if (from.path === '/personalCenter/messageCenter') { // 从消息中心跳转过来的
const applyId = to.query.applyId
if (applyId) {
vm.$utils.scrollDocument(800, true)
vm.handleSplitOrderDetail(Number(applyId))
} else {
vm.$utils.scrollDocument(700, true)
}
}
})
},