前端的路由從后台獲取,包括權限;
大體步驟包括:路由攔截(鈎子函數)---->后台獲取路由數據 ----> 保存到本地或vuex中.
在router-->index.js中:
1 router.beforeEach((to, from, next) => { //攔截處一定要else{} 2 // 加載動態菜單和路由 3 if (to.path === '/') { 4 addDynamicMenuAndRoutes(to, from) 5 console.log(router.options.routes); 6 next() 7 } else { 8 if (store.state.menu.navTree) { 9 addDynamicMenuAndRoutes(to, from) 10 } 11 next() 12 } 13 })
一個Tip,鈎子函數一定要記得else{},就這個小問題找了半天,各種排除。。。
我這里沒有登錄驗證,所以通過path來判斷是否加載動態路由;
下面的判斷是由於vuex在F5刷新時會清空,所以通過里面是否有vuex里的某個狀態來判斷是否要再次加載路由;一般用登錄的token判斷;
下面是加載動態路由的關鍵函數:
1 /** 2 * 加載動態菜單和路由 3 */ 4 function addDynamicMenuAndRoutes(to, from) { 5 // 處理IFrame嵌套頁面 6 handleIFrameUrl(to.path) 11 api.menu.findMenuTree() 12 .then(res => { 13 // 添加動態路由 14 console.log(res.data) 15 let dynamicRoutes = addDynamicRoutes(res.data) 16 // 處理靜態組件綁定路由 17 handleStaticComponent(router, dynamicRoutes) 18 router.addRoutes(router.options.routes) 19 console.log(router.options.routes) 20 // 保存加載狀態 21 store.commit('menuRouteLoaded', true) 22 // 保存菜單樹 23 store.commit('setNavTree', res.data) 24 }).then(res => { 25 // api.user.findPermissions({ 'name': userName }).then(res => { 26 // // 保存用戶權限標識集合 27 // store.commit('setPerms', res.data) 28 // }) 29 }) 30 .catch(function(res) {}) 31 }
添加動態路由:
1 /** 2 * 添加動態(菜單)路由 3 * @param {*} menuList 菜單列表 4 * @param {*} routes 遞歸創建的動態(菜單)路由 5 */ 6 function addDynamicRoutes(menuList = [], routes = []) { 7 var temp = [] 12 for (var i = 0; i < menuList.length; i++) { 13 if (menuList[i].children && menuList[i].children.length >= 1) { 14 temp = temp.concat(menuList[i].children) 15 } else if (menuList[i].url && /\S/.test(menuList[i].url)) { 16 //menuList[i].url = menuList[i].url.replace(/^\//, '') 17 menuList[i].url = menuList[i].url.substring(1); 18 try { 19 // 根據菜單URL動態加載vue組件,這里要求vue組件須按照url路徑存儲 20 // 如url="sys/user",則組件路徑應是"@/views/sys/user.vue",否則組件加載不到 21 let array = menuList[i].url.split('/') 22 let url = '' 23 for (let i = 0; i < array.length; i++) { 24 url += array[i].substring(0, 1).toUpperCase() + array[i].substring(1) + '/' 25 } 26 url = url.substring(0, url.length - 1) 27 var route = { 28 path: menuList[i].url, 29 component: resolve => require([`@/views/${url}`], resolve), 30 name: menuList[i].name, 31 meta: { 32 icon: menuList[i].icon, 33 index: menuList[i].id 34 } 35 } 36 } catch (e) {} 37 // } 38 routes.push(route) 39 } 40 } 41 if (temp.length >= 1) { 42 addDynamicRoutes(temp, routes) 43 } else { 44 // console.log('動態路由加載...') 45 // console.log('動態路由加載完成.') 46 } 47 return routes 48 }
模擬后台的路由數據:
1 "data": [{ 2 "id": 1, 3 "createBy": null, 4 "createTime": null, 5 "lastUpdateBy": null, 6 "lastUpdateTime": null, 7 "parentId": 0, 8 "name": "系統配置", 9 "url": null, 10 "perms": null, 11 "type": 0, 12 "icon": "el-icon-setting", 13 "orderNum": 0, 14 "delFlag": 0, 15 "parentName": null, 16 "level": 0, 17 "children": [{ 18 "id": 2, 19 "createBy": null, 20 "createTime": null, 21 "lastUpdateBy": null, 22 "lastUpdateTime": null, 23 "parentId": 1, 24 "name": "角色配置", 25 "url": "/sys/user", 26 "perms": null, 27 "type": 1, 28 "icon": "el-icon-service", 29 "orderNum": 1, 30 "delFlag": 0, 31 "parentName": "系統配置", 32 "level": 1, 33 "children": [] 34 }, { 35 "id": 3, 36 "createBy": null, 37 "createTime": null, 38 "lastUpdateBy": null, 39 "lastUpdateTime": null, 40 "parentId": 1, 41 "name": "業務配置", 42 "url": "/sys/dept", 43 "perms": null, 44 "type": 1, 45 "icon": "el-icon-news", 46 "orderNum": 2, 47 "delFlag": 0, 48 "parentName": "系統配置", 49 "level": 1, 50 "children": [] 51 }, { 52 "id": 4, 53 "createBy": null, 54 "createTime": null, 55 "lastUpdateBy": null, 56 "lastUpdateTime": null, 57 "parentId": 1, 58 "name": "權限配置", 59 "url": "/sys/role", 60 "perms": null, 61 "type": 1, 62 "icon": "el-icon-view", 63 "orderNum": 4, 64 "delFlag": 0, 65 "parentName": "系統配置", 66 "level": 1, 67 "children": [] 68 }, { 69 "id": 5, 70 "createBy": null, 71 "createTime": null, 72 "lastUpdateBy": null, 73 "lastUpdateTime": null, 74 "parentId": 1, 75 "name": "流程控制", 76 "url": "/sys/menu", 77 "perms": null, 78 "type": 1, 79 "icon": "el-icon-menu", 80 "orderNum": 5, 81 "delFlag": 0, 82 "parentName": "系統配置", 83 "level": 1, 84 "children": [] 85 }, 86 { 87 "id": 7, 88 "createBy": null, 89 "createTime": null, 90 "lastUpdateBy": null, 91 "lastUpdateTime": null, 92 "parentId": 1, 93 "name": "大數據", 94 "url": "/sys/dict", 95 "perms": null, 96 "type": 1, 97 "icon": "el-icon-edit-outline", 98 "orderNum": 7, 99 "delFlag": 0, 100 "parentName": "系統配置", 101 "level": 1, 102 "children": [] 103 }, 104 { 105 "id": 8, 106 "createBy": null, 107 "createTime": null, 108 "lastUpdateBy": null, 109 "lastUpdateTime": null, 110 "lastUpdateTime": "2018-09-23T11:32:28.000+0000", 111 "parentId": 1, 112 "name": "數據過濾", 113 "url": "/sys/log", 114 "perms": "sys:log:view", 115 "type": 1, 116 "icon": "el-icon-info", 117 "orderNum": 8, 118 "delFlag": 0, 119 "parentName": "系統配置", 120 "level": 1, 121 "children": [] 122 }, { 123 "id": 9, 124 "createBy": null, 125 "createTime": null, 126 "lastUpdateBy": "admin", 127 "lastUpdateTime": "2018-09-23T11:32:28.000+0000", 128 "parentId": 1, 129 "name": "系統維護", 130 "url": "/sys/dispose", 131 "perms": "sys:dispose:view", 132 "type": 1, 133 "icon": "el-icon-info", 134 "orderNum": 9, 135 "delFlag": 0, 136 "parentName": "系統配置", 137 "level": 1, 138 "children": [] 139 } 140 ] 141 } 142 ]
本文主要參考 朝雨憶輕塵,感謝大佬的詳細介紹。