vue-router3.x和vue-router4.x相互影响的问题记录

Posted Shapeying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue-router3.x和vue-router4.x相互影响的问题记录相关的知识,希望对你有一定的参考价值。

背景

项目中有一个系统使用的微前端,主站使用是vue2实现的,使用的是vue-router3.x。子应用有使用vue3实现的,使用的为vue-router4.x
该子应用中的页面A有通过操作按钮触发跳转到其他子应用页面B的需求,此时使用的是vue-router4.x的编程式导航API。
当通过点击主站的Tab切换回B的时候,使用的是主站的vue-router.3.x,到目前为止,都很正常。
但再次通过A的按钮触发跳转到B时,就会出现 http://xxxxxundefined路径,导致页面空白。

分析

通过一步步断点,追踪问题。

第一次触发跳转时

第二次触发跳转时

当vue-router4.x进行导航时,会先从history.state中获取一个current字段,而vue-router3.x切换时,导致该字段丢失了,所以最终push的路径为undefined。

解决

在vue3的子应用中增加以下导航守卫,手动增加current字段。

router.beforeEach(() => 
  // 修复通过菜单切换后(主站使用的为vue-router3.x)导致 history.state中丢失关键信息
  // 再次通过vue-router4.x 的 router进行切换时,跳转到 xxxxundefined/路径的问题
  if (!history.state.current) 
    history.state.current = window.location.pathname;
  
);

Vue-Router相关

一 vue-router是什么?

  vue-router是Vue的路由系统,定位资源的,可以不进行整页刷新去切换页面内容。

二 vue-route安装和配置

  vue-router.js 可以下载 也可以用cdn。

 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

三 路由的一些方法

  1.路由的注册/命名路由/路由的参数   

 1 <div id="app">
 2     <router-link :to="{name:‘home‘}">首页</router-link>
 3     <router-link :to="{name:‘login‘}">登录页面</router-link>
 4     <router-link to="/wdb?age=20">用户页面</router-link>
 5     <router-view></router-view>
 6 </div>
 7 <script>
 8     let url=[
 9         {
10             path:/,
11             name:home,       **********命名路由
12             component:{
13                 template:`<div>
14                                 <h1>这是首页</h1>
15                                 <h2>首页内容</h2>
16                            </div>`
17             }
18         },
19         {
20             path:/login,
21             name:login,
22             component:{
23                 template:`<div><h1>这是登录页面</h1></div>`,
24             }
25         },
26         {
27             path:/:username,
28             name:user,
29             component: {
30                 template: `<div>
31                         <h1>这是用户页面</h1>
32                         <p>用户名{{$route.params.username}}</p>
33                         <p>年龄{{$route.query.age}}</p>
34                         </div>`
35             }
36         }
37     ];
38     let my_router=new VueRouter({
39         routes:url,
40     });
41     const app=new Vue({
42         el:#app,
43         router:my_router,
44         mounted(){
45             console.log(this.$route);
46             console.log(this.$router);
47             console.log(this.$el)
48         }
49     })
50 </script>

  2.子路由注册

 1 <div id="app">
 2     <router-link :to="{name:‘home‘}">首页</router-link>
 3     <router-view></router-view>
 4 </div>
 5 <script>
 6     let routes=[
 7         {
 8             path:/,
 9             name:home,
10             redirect:/wdb,
11             component:{
12                 template:`<div>
13                             <h1>这是首页</h1>
14                             <router-link to="wdb">WDB</router-link>
15                             <router-link to="hgg">HGG</router-link>
16                             <router-view></router-view>
17                             </div>`
18             },
19             children:[
20                 {
21                     path:‘/wdb‘,
22                     name:‘wdb‘,
23                     component: {
24                     template: `<div><h1>WDB</h1></div>`,
25                     }
26                 },
27                 {
28                     path:‘/hgg‘,
29                     name:‘hgg‘,
30                     component: {
31                     template: `<div><h1>HGG</h1></div>`,
32                     }
33                 },
34             ]
35         }
36     ];
37     let router = new VueRouter({
38         routes:routes
39     });
40     const app=new Vue({
41         el:#app,
42         router:router,
43     })
44 </script>

  3.手动路由

 1 <div id="app">
 2     <router-link :to="{name: ‘home‘}">首页</router-link>
 3     <router-link :to="{name: ‘login‘}">登录</router-link>
 4     <router-link to="/user/wdb?age=22">用户页面</router-link>
 5     <router-view></router-view>
 6 </div>
 7 <template id="my_user">
 8         <div>
 9             <h1>这是用户页面</h1>
10             <p>用户名{{$route.params.username}}</p>
11             <p>年龄{{$route.query.age}}</p>
12             <button @click="my_click">点我调转到首页</button>
13         </div>
14  </template>
15 <script>
16     let url=[
17         {
18            path:/,
19             name:home,
20             component:{
21                template:`<div>
22                                 <h1>这是首页</h1>
23                                 <router-link to="/liuye">也哥</router-link>
24                                 <router-link to="/fengkun">小弟</router-link>
25                                 <router-view></router-view>
26                                 </div>`
27             },
28             children : [
29                 {
30                     path: "/liuye",
31                     component: {
32                          template: `<div><h1>这是也哥地盘</h1></div>`
33                     }
34                 },
35                 {
36                     path: "/fengkun",
37                     component: {
38                          template: `<div><h1>这是也哥小弟的地盘</h1></div>`
39                     }
40                 },
41              ],
42         },
43         {
44             path:/login,
45             name:login,
46             component:{
47                 template:`<div>
48                             <h1>这是登录页面</h1>
49                             <button @click="my_click">点我跳转到用户页面</button>
50                                 </div>`,
51                 methods:{
52                     my_click:function () {
53                         this.$router.push({name:user,params:{username:wdb},query:{age:22}})
54                     }
55                 }
56             }
57         },
58         {
59             path: "/user/:username",
60             name: "user",
61             component: {
62                 template: "#my_user",
63                 methods: {
64                     my_click: function () {
65                         // 跳转到首页
66                         // this.$router.push({name: "home"})
67                     }
68                 }
69             }
70         }
71     ];
72     let router=new VueRouter({
73         routes:url,
74     });
75     const app=new Vue({
76         el:#app,
77         router:router,
78         mounted(){},
79     })
80 </script>

  4.命名的路由视图

 1 <div id="app">
 2     <router-link :to="{name: ‘home‘}">首页</router-link>
 3     <router-link :to="{name: ‘login‘}">登录</router-link>
 4     <router-link to="/user/wdb?age=22">用户页面</router-link>
 5     <router-view name="my_header"></router-view>
 6     <router-view name="my_footer"></router-view>
 7     <router-view></router-view>
 8 </div>
 9 <template id="my_user">
10         <div>
11             <h1>这是用户页面</h1>
12             <p>用户名{{$route.params.username}}</p>
13             <p>年龄{{$route.query.age}}</p>
14             <button @click="my_click">点我调转到首页</button>
15         </div>
16  </template>
17 <script>
18     let url=[
19         {
20             path: /,
21             name: home,
22             components: {
23                 my_header: {
24                     template: `<div><h1>这是头部组件</h1></div>`
25                 },
26                 my_footer: {
27                     template: `<div><h1>这是底部组件</h1></div>`
28                 },
29             },
30         },
31         {
32             path:/login,
33             name:login,
34             component:{
35                 template:`<div>
36                             <h1>这是登录页面</h1>
37                             <button @click="my_click">点我跳转到用户页面</button>
38                                 </div>`,
39                 methods:{
40                     my_click:function () {
41                         this.$router.push({name:user,params:{username:wdb},query:{age:22}})
42                     }
43                 }
44             }
45         },
46         {
47             path: "/user/:username",
48             name: "user",
49             component: {
50                 template: "#my_user",
51                 methods: {
52                     my_click: function () {
53                         // 跳转到首页
54                         // this.$router.push({name: "home"})
55                     }
56                 }
57             }
58         }
59     ];
60     let router=new VueRouter({
61         routes:url,
62     });
63     const app=new Vue({
64         el:#app,
65         router:router,
66         mounted(){},
67     })
68 </script>

  5.路由的钩子

 1 <div id="app">
 2      <router-link :to="{name: ‘home‘}">首页</router-link>
 3     <router-link :to="{name: ‘login‘}">登录</router-link>
 4     <router-link to="/user/caizhuang?age=48">用户页面</router-link>
 5     <router-view></router-view>
 6 </div>
 7 <script>
 8     let url=[
 9         {
10         path:/,
11         name:home,
12         meta:{
13             required_login:false,
14         },
15         component:{
16             template:`<div>
17                                 <h1>这是首页</h1>
18                                 <router-link to="/liuye">也哥</router-link>
19                                 <router-link to="/fengkun">小弟</router-link>
20                                 <router-view></router-view>
21                                 </div>`
22         },
23             children:[
24                 {
25                     path: "/liuye",
26                     meta: {
27                       required_login: true
28                     },
29                     component: {
30                          template: `<div><h1>这是也哥地盘</h1></div>`
31                     }
32                 },
33                 {
34                     path: "/fengkun",
35                     component: {
36                          template: `<div><h1>这是也哥小弟的地盘</h1></div>`
37                     }
38                 }
39             ]
40     },
41         {
42             path: "/login",
43             name: "login",
44             component: {
45                 template: `<div><h1>这是登录页面</h1></div>`
46             }
47         },
48         {
49             path: "/user/:username",
50             meta: {
51               required_login: true
52             },
53             name: "user",
54             component: {
55                 template: `<div>
56                                 <h1>这是用户页面</h1>
57                                 <p>用户名{{$route.params.username}}</p>
58                                 <p>年龄{{$route.query.age}}</p>
59                                 </div>`
60             }
61         }
62     ];
63     let router=new VueRouter({
64         routes:url,
65     });
66     router.beforeEach(function (to,from,next) {
67         if(to.meta.required_login){
68             next(/login)
69         }else{
70             next()
71         }
72     });
73     const app=new Vue({
74         el:#app,
75         router:router,
76         mounted(){}
77     })
78 </script>

  next参数详解

1 next:function  一定要调用这个方法来resolve这个钩子函数。
2         执行效果依赖next方法的调用参数
3         next() 什么都不做继续执行到调转的路由
4         next(false) 中断当前导航 没有跳转 也没有反应
5         next("/")  参数是路径 跳转到该路径
6         next(error)  如果next参数是一个Error实例 导航终止该错误
7                     会传递给router.onError()注册过的回调中

 

以上是关于vue-router3.x和vue-router4.x相互影响的问题记录的主要内容,如果未能解决你的问题,请参考以下文章

vue 3.x vue-router使用

降低vue-router版本的两种方法

Vue-Router

vue-router4.x教程

Vue-Router4/TypeScript“没有重载匹配这个调用”

vue路由核心要点(vue-router)