路由跳转的几种方式
一、声明式导航
一开始写样式我们写的是a标签,在响应式设计的时候就改成router-link,实质也是一种a标签。声明式导航务必要有to属性,比如<router-link to="/login" >登录</router-link>
两个例子:
1.跳转路由并携带query参数 to的字符串写法
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>
2.跳转路由并携带query参数 to的对象写法
<router-link :to="{
path:'/home/message/detail',
query:{
id:m.id,
title:m.title
}
">
二、编程式导航
利用组件实例的$router.push/replace方法可以实现路由跳转
首先在button添加一个click方法 比如我这里的例子是 @click="goSearch"
然后在script中暴露方法method
goSearch(){
//搜索按钮的回调函数:需要向search路由进行跳转
this.$router.push("/search")
}
但是!有一个问题:为什么编程式导航多次执行会有NavigationDuplicated的警告
因为最新的vue-router引入promise函数,但promise需要一个T/F结果
解决方法如下:通过给push方法传入相应的成功和失败的回调函数,可以捕获到当前错误,这样可以解决这个问题。
比如:
this.$router.push({name:"search",params:{keyword:this.keyword || undefined},query:{k:this.keyword.toUpperCase()}},()=>{},()=>{})
这种方法可以解决这个问题,但是这治标不治本,想要之后不再出现这个问题,最好的解决方法就是要么用声明式导航不要用编程式导航 ,要么就重写push和replace
重写push和replace
在router配置中加入下面这个代码(通用的,直接加进去就好):
//先把VueRouter原型对象的push保存一份
let originPush=VueRouter.prototype.push
let originReplace=VueRouter.prototype.replace
//重写push和replace
//参数:replace:告诉原来的push方法往哪里跳(传递哪些参数) resolve:成功的回调 reject:失败的回调
VueRouter.prototype.push=function(location,resolve,reject){
if(resolve && reject){
//call和apply的区别:
//相同点:都可以调用函数一次,都可以篡改函数的上下文一次
//不同点:call传递参数用逗号隔开,apply方法执行,传递数组
originPush.call(this,location,resolve,reject);
}else{
originPush.call(this,location,()=>{},()=>{})
}
}
VueRouter.prototype.replace=function(location,resolve,reject){
if(resolve && reject){
//call和apply的区别:
//相同点:都可以调用函数一次,都可以篡改函数的上下文一次
//不同点:call传递参数用逗号隔开,apply方法执行,传递数组
originReplace.call(this,location,resolve,reject);
}else{
originReplace.call(this,location,()=>{},()=>{})
}
}