Vue動態路由,結合后端接口實現


話不多說,直接上干貨。

首先聲明我們的固定路由,后面系統需要用到的路由則可以在此基礎上進行動態添加。

 1 //固定的路由
 2   const routes = [{
 3       path: '/',
 4       component: login,
 5       meta: {
 6         title: '登錄',
 7         Breadcrumb: false
 8       },
 9       isHidden: true, //是否隱藏
10       children: []
11     },
12     {
13       path: '/login',
14       component: login,
15       meta: {
16         title: '登錄',
17         Breadcrumb: false
18       },
19       isHidden: true, //是否隱藏
20       children: []
21     },
22   ]

此處用到自定義字典結構dictionary.js;

 //dictionary.js;
1
var list = []; 2 class dictionary { 3 set(key, value) { 4 list.push({ 5 key: key, 6 value: value, 7 }) 8 } 9 get(key) { 10 var component=null; 11 list.forEach(item => { 12 if (item.key == key) 13 component=item.value; 14 }) 15 16 return component; 17 } 18 } 19 20 export default dictionary

系統登錄時調用方法同步獲取當前的擁有權限的菜單

 1 //獲取動態路由方法
 2 async function getRouterList(that,postFun,successCallback) {
 3   routerPath = '';
 4   //登錄之后獲取動態路由
 5   let userRouter = [];
 6   let userMenu = [];
 7   var data = await getData();
 8   userRouter = data; //獲取路由
 9   userRouter = sort(userRouter);
10   //從接口獲取菜單路由
11   function getData() {
12     return new Promise(resolve => {
13       let para = {
14         urls: '后端獲取權限列表的接口地址',
15         isShowLoading: false,//是否顯示加載狀態
16       };
17       postFun(para).then(res => {
18         if (res.code == 200) {
19           data = res.value;
20           if (!data) {
21             that.$message.error('你沒有任何權限請聯系管理員分配權限');
22             that.$router.push('/login');
23           } else {
24             resolve(data);
25           }
26         } else {
27           that.$message.error('獲取權限失敗,請稍后重試');
28           that.$router.push('/login');
29         }
30       }).catch(err => {
31 
32       });
33     });
34   }

獲取到權限結構后組裝成路由格式並調用路由拼接將系統路由組織完整

routes.concat(userRouter)

此時如果用戶強制刷新瀏覽器,將再次獲取當前的路由以確定權限是否有變化保證當前用戶的權限始終保持與后台配置一致。

具體做法在main.js中添加邏輯判斷代碼如下:

 1 if (sessionStorage.getItem('token')) {
 2   //這里是調用router.js里的方法拿到動態路由
 3   Vue.prototype._router.getRouterList(Vue,Vue.prototype.postFun, function(routerData, userMenu) {
 4     //動態添加路由
 5     router.addRoutes(routerData)
 6     router.options.routes = [...userMenu];
 7   })
 8 } else {
 9   router.push('/login');
10 }
11 //路由守衛
12 router.beforeEach((to, from, next) => {
13   //NProgress.start();
14   if (to.path == '/login') {
15     sessionStorage.removeItem('token');
16   }
17   let user = sessionStorage.getItem('token');
18   if (!user && to.path != '/login') {
19     next({
20       path: '/login'
21     })
22   }
23   next();
24 })

 

這樣就完成了我們vue的動態路由和使用。完整的動態路由router.js代碼如下:

  1 import dictionary from './dictionary'
  2 const login = () => import('@/views/login/login')
  3 const home = () => import('@/views/master/Home')
  4 var routerPath = '';
  5 
  6 var map = new dictionary();
  7 /*------------------------------------------主頁-------------------------------------------------------------------------*/
  8 map.set("home",resolve => require(['@/views/home/home'], resolve));
  9 /*-------------------------------------------系統-------------------------------------------------------------------------*/
 10 map.set("roleManagement",resolve => require(['@/views/systemManagement/roleManagement/roleList'], resolve)) //系統角色管理
 11 map.set("systemUserManagement",resolve => require(['@/views/systemManagement/systemUserManagement/systemUserList'], resolve)); //系統用戶管理
 12 map.set("menuManagement",resolve => require(['@/views/systemManagement/menuManagement/menuList'], resolve)); //菜單管理
 13 map.set("fileManagement",resolve => require(['@/views/systemManagement/fileManagement/fileList'], resolve)); //文件管理
 14 map.set("contentManagement",resolve => require(['@/views/systemManagement/contentManagement/contentList'], resolve)); //內容管理
 15 map.set("smsSendRecord",resolve => require(['@/views/systemManagement/smsSendRecord/smsSendRecordList'], resolve)); //短信
 16 /*-----------------------------------------------賽事管理-------------------------------------------------------------------------*/
 17 map.set("scorerLoginPage",resolve => require(['@/views/matchManagement/scorerLoginPage/scorerLoginPageList'], resolve)); //記分長登錄頁管理
 18 map.set("match",resolve => require(['@/views/matchManagement/match/matchList'], resolve)); //比賽管理
 19 map.set("accountAuthorization",resolve => require(['@/views/matchManagement/accountAuthorization/accountAuthorList'], resolve)); //賬號授權管理
 20 /*-----------------------------------------------用戶管理-------------------------------------------------------------------------*/
 21 map.set("user",resolve => require(['@/views/userManagement/users/userList'], resolve)); //用戶列表
 22 map.set("orderMatch",resolve => require(['@/views/userManagement/orderMatch/orderList'], resolve)); //賽事訂單管理
 23 map.set("orderReal",resolve => require(['@/views/userManagement/orderReal/orderList'], resolve)); //實名訂單管理
 24 map.set("player",resolve => require(['@/views/userManagement/player/playerList'], resolve)); //選手列表
 25 map.set("qrCode",resolve => require(['@/views/userManagement/qrCode/qrCodeList'], resolve)); //二維碼數據
 26 
 27 
 28 //獲取動態路由方法
 29 async function getRouterList(that,postFun,successCallback) {
 30   routerPath = '';
 31   //登錄之后獲取動態路由
 32   let userRouter = [];
 33   let userMenu = [];
 34   var data = await getData();
 35   userRouter = data; //獲取路由
 36   userRouter = sort(userRouter);
 37   //從接口獲取菜單路由
 38   function getData() {
 39     return new Promise(resolve => {
 40       let para = {
 41         urls: '/sys/account/permissions',
 42         isShowLoading: false,
 43       };
 44       postFun(para).then(res => {
 45         if (res.code == 200) {
 46           data = res.value;
 47           if (!data) {
 48             that.$message.error('你沒有任何權限請聯系管理員分配權限');
 49             that.$router.push('/login');
 50           } else {
 51             resolve(data);
 52           }
 53         } else {
 54           that.$message.error('獲取權限失敗,請稍后重試');
 55           that.$router.push('/login');
 56         }
 57       }).catch(err => {
 58 
 59       });
 60     });
 61   }
 62   //路由菜單排序
 63   function sort(userRouter) {
 64     var router = [];
 65     var routerTo = [];
 66     userRouter.forEach(item => {
 67       if (item.parentId ==-1) {
 68         var children = [];
 69         var menuChildren = [];
 70         router.push({
 71           sort: item.sort,
 72           path: '/',
 73           component: home,
 74           icon: item.icon,
 75           key: item.id,
 76           meta: {
 77             title: item.name,
 78             Breadcrumb: isHaveSubMenus(userRouter, item.id),
 79           },
 80           isHidden: false, //是否隱藏
 81           children: children,
 82         });
 83         //菜單
 84         userMenu.push({
 85           sort: item.sort,
 86           path: item.path,
 87           icon: item.icon,
 88           key: item.id,
 89           meta: {
 90             title: item.name,
 91             Breadcrumb: true
 92           },
 93           isHidden: false, //是否隱藏
 94           children: menuChildren,
 95         });
 96 
 97         if (!isHaveSubMenus(userRouter, item.id)) {
 98           children.push({
 99             sort: item.sort,
100             path: item.path,
101             icon: item.icon,
102             key: item.id,
103             meta: {
104               title: item.name,
105               Breadcrumb: true
106             },
107             isHidden: false,
108             component: map.get(item.path.split('/')[1]),
109           });
110         }
111         getSubMenus(item, userRouter, children, menuChildren);
112       }
113     });
114     router.sort(sortASC);
115     userMenu.sort(sortASC);
116     //獲取第一個菜單路由
117     userMenu.forEach(item1 => {
118       if (routerPath == '' && item1.path != '/') {
119         routerPath = item1.path;
120       }
121     });
122     if (routerPath == '') {
123       userMenu.forEach(item => {
124         if (item.children && item.children.length > 0) {
125           item.children.forEach(itemSub => {
126             if (routerPath == '') {
127               routerPath = itemSub.path;
128             }
129           })
130         }
131       })
132     }
133     return router;
134   }
135 
136   function isHaveSubMenus(menus, parentId) {
137     var list = [];
138     menus.forEach(item => {
139       if (item.parentId == parentId)
140         list.push(item.id);
141     });
142 
143     return list.length > 0;
144   }
145   //獲取子菜單路由
146   function getSubMenus(parent, data, children, menuChildren) {
147     data.forEach(item => {
148       if (item.parentId == parent.id) {
149         //路由
150         children.push({
151           sort: item.sort,
152           path: item.path,
153           icon: item.icon,
154           key: item.id,
155           meta: {
156             title: item.name,
157             Breadcrumb: true
158           },
159           isHidden: false,
160           component: map.get(item.path.split('/')[1]),
161         });
162         //菜單
163         menuChildren.push({
164           sort: item.sort,
165           path: item.path,
166           icon: item.icon,
167           key: item.id,
168           meta: {
169             title: item.name,
170             Breadcrumb: true
171           },
172           isHidden: false, //是否隱藏
173         });
174       }
175     });
176     if (children.length > 0)
177       children.sort(sortASC);
178     if (menuChildren.length > 0)
179       menuChildren.sort(sortASC);
180   }
181 
182   function sleep(time) {
183     return new Promise((resolve) => setTimeout(resolve, time));
184   }
185 
186   //固定的路由
187   const routes = [{
188       path: '/',
189       component: login,
190       meta: {
191         title: '登錄',
192         Breadcrumb: false
193       },
194       isHidden: true, //是否隱藏
195       children: []
196     },
197     {
198       path: '/login',
199       component: login,
200       meta: {
201         title: '登錄',
202         Breadcrumb: false
203       },
204       isHidden: true, //是否隱藏
205       children: []
206     },
207   ]
208   successCallback(routes.concat(userRouter), userMenu, routerPath)
209 }
210 export default {
211   getRouterList,
212 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM