声明式导航是没有这些问题的,因为vue-router底层已经处理好了
# 为什么编程式路由导航就有这个问题呢
因为新的版本vue-router引入了promise
this.$router.push返回promise
# 方法一:要给push()返回的promise传入成功或失败的回调函数可以解决,但每次都得传回调,不方便
# 方法二:重写路由器原型对象上的push方法
第一种重写方式
// 先把router原型对象上的push先保存一份
const originalPush = router.prototype.push
const originalReplace = router.prototype.replace
// 重写push方法
// 参数location:告诉原来的push方法,往哪里跳转以及传递哪些参数,resolve是成功的回调,reject是失败的回调
router.prototype.push = function push(location,resolve,reject) {
// 如果resolve和reject都传递了,就调用原来的push()方法
if(resolve&&reject){
// call和apply的区别:都可以调用函数一次,都可以改变this的指向
// 不同点:call传递的参数用逗号隔开,apply传递的参数为数组
originalPush.call(this,location,resolve,reject)
}else{
originalPush.call(this, location,()=>{},()=>{})
}
}
第二种重写方式
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
const originalReplace = Router.prototype.replace
Router.prototype.replace = function replace (location) {
return originalReplace.call(this, location).catch(err => err)
}
注:replace同上