当我们在使用编程式路由实现跳转的时候,多次执行会抛出NavigationDuplicated的警告错误是因为"vue-router"3版本之后 底层引入了promise。而我们通过声明式导航没有出现此类问题是因为vue-router底层已经处理好了。
出现问题如下:
解决方法1. 在我们使用编程式导航时,通过给push或replace方法传递相应的成功和失败的回调函数可以捕获到当前的错误解决此问题 如:
//编程式导航
this.$router.push({
name:'search',},()=>{},()=>{})
//添加 ()=>{},()=>{} 解决此问题
解决方法1可以解决此问题,但不是最好,因为将来在别的组件当中使用push
replace,编程式导航还是需要做次操作。
解决方法2:通过修改VueRouter中push|replace方法源码
因为push|replace方法是VueRouter类的一个实例,是原型对象方法关系如下:
//原型对象的方法
VueRouter.prototype.push=function(){
//函数的上下文为VueRouter类的一个实例
}
let $router=new VUERouter();
//router是VueRouter()的实例对象 所以可以使用到push|replace方法
$router.push(xxx);
//编程式导航实现跳转
this.$router.push();
所以我们可以通过对原型方法push进行修改,修改的结果会作用于组件实例的$router的实例
首先我们先保存VueRouter原型对象的push 保存 然后修改封装解决问题
直接以下代码复制到路由配置文件就可以了。
//保存下来push方法 将来我们还会用到原push方法进行路由跳转
let originPush=VueRouter.prototype.push;
//接下来我们重写push|replace方法
//第一个参数location参数像原push方法声明跳转的地方 resolve和reject传递成功与失败
VueRouter.prototype.push=function(location,resolve,reject){
if(resolve && reject){
//如果成功 调用原来的push方法
originPush.call(this,location,resolve,reject);
}else{
originPush.call(this,location,()=>{},()=>{}); }
}
此外扩展知识:call||apply区别 相同点都可以调用函数一次,都可以篡改函数上下文一次 不同点在于call传参用逗号隔开,apply方法执行,传递数组