3_编程式导航路由跳转到当前路由(参数不变),多次执行报告NavigationDuplicated错误的解决方案

1、路由跳转的方式

声明式导航  <router-link to="">

编程式导航   this.$router.push()/replace()

 

 2、路由携带的参数

2.1 query参数

 1 <!-- 跳转并携带query参数,to的字符串写法 -->
 2 <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
 3                 
 4 <!-- 跳转并携带query参数,to的对象写法 -->
 5 <router-link 
 6     :to="{
 7         path:'/home/message/detail',
 8         query:{
 9            id:666,
10             title:'你好'
11         }
12     }"
13 >跳转</router-link>
使用path
 1 ************************************************
 2 {
 3     path:'/demo',
 4     component:Demo,
 5     children:[
 6         {
 7             path:'test',
 8             component:Test,
 9             children:[
10                 {
11                       name:'hello' //给路由命名
12                     path:'welcome',
13                     component:Hello,
14                 }
15             ]
16         }
17     ]
18 }
19 
20 ************************************************
21 <!--简化前,需要写完整的路径 -->
22 <router-link to="/demo/test/welcome">跳转</router-link>
23 
24 <!--简化后,直接通过名字跳转 -->
25 <router-link :to="{name:'hello'}">跳转</router-link>
26 
27 <!--简化写法配合传递参数 -->
28 <router-link 
29     :to="{
30         name:'hello',
31         query:{
32            id:666,
33             title:'你好'
34         }
35     }"
36 >跳转</router-link>
命名路由+使用name传递

2.2 params参数

声明路由
*************************************
{
    path:'/home',
    component:Home,
    children:[
        {
            path:'news',
            component:News
        },
        {
            component:Message,
            children:[
                {
                    name:'xiangqing',
                    path:'detail/:id/:title', //使用占位符声明接收params参数
                    component:Detail
                }
            ]
        }
    ]
}

使用name传参
******************************************
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link :to="/home/message/detail/666/你好">跳转</router-link>
                
<!-- 跳转并携带params参数,to的对象写法 -->
<router-link 
    :to="{
        name:'xiangqing',
        params:{
           id:666,
            title:'你好'
        }
    }"
>跳转</router-link>
只用name

如何指定params参数可传可不传?  

  path: '/search/:keyword?'

如果指定name与params配置, 但params中数据是一个"", 无法跳转

  解决1: 不指定params

  解决2: 指定params参数值为undefined

 路由组件能不能传递props数据?

  可以将query或且params参数映射/转换成props传递给路由组件对象

  实现: props: (route)=>({keyword1:route.params.keyword, keyword2: route.query.keyword })

 

 3、编程式路由跳转到当前路径且参数没有变化时会抛出 NavigationDuplicated 错误

vue-router3.1.0之后, 引入了push()的promise的语法, 如果没有通过参数指定回调函数就返回一个promise来指定成功/失败的回调, 且内部会判断如果要跳转的路径和参数都没有变化, 会抛出一个失败的promise

最佳解决方法:重写Vue原型上的push和replace方法

/需要重写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修改上下文,变为(路由组件.$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,
      () => {},
      () => {}
    );
  }
};
重写push和replace

 

posted @ 2022-03-08 18:02  踏燕白梅  阅读(149)  评论(0)    收藏  举报