编程式导航(push|replace)才会有这种情况的异常,但这种异常对于程序没有任何影响
声明式导航内部已经解决这种问题。
由于vue-router引入了promise,push方法返回值是promise,当传递参数多次且重复,会抛出异常,需要传入相应的成功的回调与失败的回调,就能捕获到promise的异常
- 第一种解决方法
this.$router.push({
name: 'search',
params: {
keyword:''||undefined
},
query: {
k: this.keyword.toLocaleUpperCase()
}
},
() => {},
(err) => {} //传两个回调
) //但只能解决当前组件问题,其他组件还是会报错
- 第二种方法,重写push方法
push方法在VueRouter的原型对象上,注册路由时组件上就添加了 r o u t e r 属性,属性值是 V u e R o u t e r 构造函数的一个实例对象,所以 t h i s . router属性,属性值是VueRouter构造函数的一个实例对象,所以this. router属性,属性值是VueRouter构造函数的一个实例对象,所以this.router.push访问的是VueRouter.prototype.push
//需要重写VueRouter.prototype原型对象身上的push|replace方法
//先把VueRouter.prototype身上的push|replace方法进行保存一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写VueRouter.prototype身上的push方法
VueRouter.prototype.push = function(location, resolve, reject) {
//第一个形参:路由跳转的配置对象(query|params)
//第二个参数:undefined|箭头函数(成功的回调)
//第三个参数:undefined|箭头函数(失败的回调)
if (resolve && reject) {
//push方法传递第二个参数|第三个参数(箭头函数)
//originPush:利用call修改上下文(this),变为(路由组件.$router)这个对象,第二参数:配置对象、第三、第四个参数:成功和失败回调函数
originPush.call(this, location, resolve, reject);
} else {
//push方法没有第二个参数|第三个参数
originPush.call(
this,
location,
() => {},
() => {}
);
}
};
//重写VueRouter.prototype身上的replace方法
VueRouter.prototype.replace = function(location, resolve, reject) {
if (resolve && reject) {
originReplace.call(this, location, resolve, reject);
} else {
originReplace.call(
this,
location,
() => {},
() => {}
);
}
};
call和apply
相同点:都可以调用函数,改变函数的上下文(this)一次,第一个参数是改变函数里面的this的指向
不同点:call传递参数用逗号隔开,apply传递的是数组