生活随笔
收集整理的這篇文章主要介紹了
Vue权限控制——动态注册路由
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
需求:實現后臺管理系統不同用戶的權限控制
根據登錄的用戶的角色動態展示后臺管理系統的左側菜單欄的菜單列表內容,然后還要動態注冊對應子菜單的路由
菜單列表內容應該通過后端接口返回:
sort為1表示當前項有子菜單sort為2表示當前項沒有子菜單,這個才是需要我們去動態注冊的組件
前端需要根據后端返回的菜單列表去動態的展示菜單列表:
并且為每個菜單列表項注冊對應的路由:
在views/main文件夾下創建所有的頁面(component)
在router/main文件夾下創建每個頁面對應的路由對象(此時只是先配置好路由path和組件component的映射關系,還沒有注冊路由,后續會根據后端返回的用戶菜單表數據(userMenus)動態的去注冊路由)
根據用戶的角色role.id向后端發送請求,拿到當前登錄用戶的userMenus菜單
根據userMenus生成對應的routes
1)先拿到項目中所有組件的路由對象route放到allRoutes數組中
2)再遞歸遍歷userMenus數組的每一項(menu),將滿足menu.url === route.path條件的menu放到routes數組中
遍歷routes數組,把數組中的每一個route通過router.addRoute('main', route),動態注冊到main路由對象的children屬性中
import type
{ RouteRecordRaw
} from 'vue-router'export function mapMenuToRoutes(userMenus: any[]): RouteRecordRaw
[] {const routes
: RouteRecordRaw
[] = []const allRoutes
: RouteRecordRaw
[] = []const routeFiles
= require
.context('../router/main', true, /\.ts/)routeFiles
.keys().forEach((key) => {console
.log(key
) const route
= require('../router/main' + key
.split('.')[1])allRoutes
.push(route
.default
)})console
.log(allRoutes
)const _recurseGetRoute = (menus: any[]) => {for (const menu
of menus
) {if (menu
.type
=== 2) {const route
= allRoutes
.find((route) => {return route
.path
=== menu
.url
})if (route
) routes
.push(route
)} else {_recurseGetRoute(menu
.children
)}}}_recurseGetRoute(userMenus
)return routes
}
<template
><div
class="nav-menu"><div
class="logo"><img src
="~@/assets/img/logo.svg" alt
="logo" /><span
class="title" v
-if="!collapse">后臺管理系統
</span
></div
><el
-menu
default-active
="1":collapse
="collapse"class="el-menu-vertical"background
-color
="#0c2135"text
-color
="#b7bdc3"unique
-openedactive
-text
-color
="#0a60bd"><template v
-for="item in userMenus" :key
="item.id"><!-- 有二級菜單的一級菜單
--><template v
-if="item.type === 1"><!-- 一級菜單
--><el
-sub
-menu
:index
="item.id + ''"><template #title
><el
-icon
><Setting
/></el
-icon
><!-- <i v
-if="item.icon" :class="item.icon"></i
> --><span
>{{ item
.name
}}</span
></template
><template v
-for="subItem in item.children" :key
="subItem.id"><!-- 二級菜單
--><el
-menu
-item
:index
="subItem.id + ''"@click
="handleMenuItemClick(subItem)"><i v
-if="subItem.icon" :class="subItem.icon"></i
><span
>{{ subItem
.name
}}</span
></el
-menu
-item
></template
></el
-sub
-menu
></template
><!-- 沒有二級菜單的一級菜單
--><template v
-else-if="item.type === 2"><!-- 一級菜單
--><el
-menu
-item
:index
="item.id + ''"><i v
-if="item.icon" :class="item.icon"></i
><span
>{{ item
.name
}}</span
></el
-menu
-item
></template
></template
></el
-menu
></div
>
</template
><script lang
="ts">
import { defineComponent
, computed
} from 'vue'
import { Setting
} from '@element-plus/icons-vue'
import { useStore
} from '@/store'
import { useRouter
} from 'vue-router'
export default defineComponent({name
: 'nav-menu',components
: { Setting
},props
: {collapse
: {type
: Boolean
,default: false}},setup(props, context) {const store
= useStore()const router
= useRouter()const userMenus
= computed(() => store
.state
.login
.userMenus
)const handleMenuItemClick = (item: any) => {router
.push({path
: item
.url
?? '/not-found'})}return {userMenus
,handleMenuItemClick
}}
})
</script
><style scoped lang
="less">
.nav
-menu
{height
: 100%;background
-color
: #
001529;
}
.logo
{display
: flex
;height
: 28px
;padding
: 12px
10px
8px
10px
;flex
-direction
: row
;justify
-content
: center
;align
-items
: center
;img
{width
: 40px
;height
: 40px
;}.title
{font
-size
: 16px
;font
-weight
: 700;color
: #fff
;}
}
.el
-menu
-vertical
{width
: 100%;height
: calc(100% - 48px
);
}
.el
-menu
{border
-right
: none
;
}
</style
>
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的Vue权限控制——动态注册路由的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。