方案一:
運用場景:系統根據登錄賬號的權限,動態加載左側菜單; 后端直接返回的路由菜單數據
實現:
------------
*解決* :這里不可以全局修改屬性值,在個別使用到的地方做css的修改。
2.2對一級菜單、二級菜單的component參數進行分別判斷
*(InitRouters中的業務邏輯,根據實際情況進行修改)*
*根據緩存中的name值去循環判斷(這里name和path在配置的時候是一致的)...實際情況判斷...*
Tip: 路由陷入無線循環的情況:
運用場景:系統根據登錄賬號的權限,動態加載左側菜單; 后端直接返回的路由菜單數據
實現:
1.獲取的數據格式
- 一級目錄component: ”components/main”
- 二級目錄component: ”components/parentView”
- 目錄下菜單component: "view/organization/user/user1.vue", //實際指向而定
- path值不可有重復指向

------------
2.將后端樹轉化為路由樹( libs/util.js )
- 遞歸樹
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//動態路由
/**
* @description 將后端菜單樹轉換為路由樹 遞歸樹
* @param {Array} menus
* @returns {Array}
*/
export const backendMenusToRouters = (menus) => {
let routers = []
forEach(menus, (menu) => {
// 將后端數據轉換成路由數據
let route = backendMenuToRoute(menu)
// 如果后端數據有下級,則遞歸處理下級
if
(menu.children && menu.children.length !== 0 && menu.name !=
""
) {
route.children = backendMenusToRouters(menu.children)
}
routers.push(route)
})
// console.log(routers)
return
routers
}
|
- 處理樹
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* @description 將后端菜單轉換為路由 處理樹
* @param {Object} menu
* @returns {Object}
*/
const backendMenuToRoute = (menu) => {
// 具體內容根據自己的數據結構來定,這里需要注意的一點是
// 原先routers寫法是component: () => import('@/view/error-page/404.vue')
// 經過json數據轉換,這里會丟失,所以需要按照上面提過的做轉換,下面只寫了核心點,其他自行處理
let route = Object.assign({}, menu)
// route.component = () => import(`/* webpackChunkName: ${menu.title} */'@/${menu.component}'`)\
// 菜單配置的時候都是矢量圖標庫里面的圖標所以要加上iconfont,ivew-admin里面都是默認的font-family:'Ionicons'=>轉成 font-family:'iconfont'
if
(menu.meta){
route.meta.icon = `iconfont ${menu.meta.icon}`
}
//矢量圖標轉划
if
(menu.component ==
"components/main"
){
route.component = Main;
//一級菜單判斷
}
else
if
(menu.component ==
"components/parentView"
){
route.component = parentView;
//二級菜單判斷
}
else
{
route.component = () => import(`@/${menu.component}`);
}
return
route
}
|
- 左側菜單數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
///////////////動態路由
/**
* @param {Array} list 通過路由列表得到菜單列表
* @param access
* @returns {Array}
*/
export const getUserMenuByRouter = (list) => {
// console.log(list)
let res = []
forEach(list, item => {
//meta沒配置,或者配置了,但hideInMenu=false
if
(!item.meta || (item.meta && !item.meta.hideInMenu)) {
let obj = {
icon: (item.meta && item.meta.icon) ||
''
,
name: item.name,
meta: item.meta
}
//有下級子元素或者showAlways=true並且還有權限訪問,繼續遞歸處理下級(item.meta && !item.meta.showAlways)
if
((hasChild(item))) {
obj.children = getUserMenuByRouter(item.children)
}
//如果配置了href,設置href
if
(item.meta && item.meta.href) obj.href = `${baseUrl}`+`${item.meta.href}`
//加入
res.push(obj)
}
})
return
res
}
|
- 后台管理踩過的坑
*解決* :這里不可以全局修改屬性值,在個別使用到的地方做css的修改。
2.2對一級菜單、二級菜單的component參數進行分別判斷
3.全局管理並緩存路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
// 獲取用戶相關信息
getUserInfo ({ state, commit }) {
let paramer ={
token:state.token,
refresData:
false
,
}
// console.log(state.token)
return
new
Promise((resolve, reject) => {
try
{
getUserInfo(paramer).then(res => {
// console.log(res)
const data = res.data.result
// console.log("菜單",JSON.stringify(data.menuRoutes))
// commit('setAvatar', data.avatar) //頭像
commit(
'setUserName'
, data.loginName)
commit(
'setUserInfo'
, data)
commit(
'setAccess'
, data.roleInfoDto.roleName)
//權限 角色
commit(
'setHasGetInfo'
,
true
)
let routers = backendMenusToRouters(data.menuRoutes)
console.log(routers)
commit(
'setRouters'
, routers)
commit(
'setHasGetRouter'
,
true
)
localStorage.setItem(
"getInfo"
,
true
);
localStorage.setItem(
"router"
, JSON.stringify(data.menuRoutes));
resolve(data)
}).
catch
(err => {
reject(err)
})
}
catch
(error) {
reject(error)
}
})
},
|
4.重置路由,在最后添加404頁面路徑
獲取到緩存里的數據,在until.js中的方法轉化后得到路由數據,最后加上404頁面路徑並重置路由*(InitRouters中的業務邏輯,根據實際情況進行修改)*
- 除了考慮正常跳轉,瀏覽器刷新,不存在的頁面地址都需考慮
- Tip:瀏覽器刷新后,路由中的name值可能會消失
*根據緩存中的name值去循環判斷(這里name和path在配置的時候是一致的)...實際情況判斷...*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
```html
// version2
const initRouters = (to, next) => {
// 在路由最后動態添加404, path:"*"
let rou = JSON.parse(localStorage.getItem(
"router"
));
let routers = backendMenusToRouters(rou);
routers.push({
path:
'*'
,
name:
'error_404'
,
meta: {
hideInMenu:
true
},
component: () => import(
'@/view/error-page/404.vue'
)
})
router.addRoutes(routers);
let arr = [];
let names2 = [];
let names = getAllNames(rou,arr);
names2= names.concat([
"login"
,
"home"
,
"error_401"
,
"error_500"
]);
console.log(names2)
let path = to.path;
let path1 = path.substr(path.lastIndexOf(
'/'
) + 1);
console.log(path1)
console.log(names2.includes(path1))
if
(to.matched.length > 0 ) {
next()
}
else
if
(to.name !==
null
&& to.matched.length === 0) {
next({
name:
'error_404'
})
return
}
else
{
next({
name: path1
})
}
}
|
Tip: 路由陷入無線循環的情況:
