生活随笔
收集整理的這篇文章主要介紹了
Vue权限控制——动态注册路由
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
需求:實(shí)現(xiàn)后臺(tái)管理系統(tǒng)不同用戶的權(quán)限控制
根據(jù)登錄的用戶的角色動(dòng)態(tài)展示后臺(tái)管理系統(tǒng)的左側(cè)菜單欄的菜單列表內(nèi)容,然后還要?jiǎng)討B(tài)注冊(cè)對(duì)應(yīng)子菜單的路由
菜單列表內(nèi)容應(yīng)該通過(guò)后端接口返回:
sort為1表示當(dāng)前項(xiàng)有子菜單sort為2表示當(dāng)前項(xiàng)沒(méi)有子菜單,這個(gè)才是需要我們?nèi)?dòng)態(tài)注冊(cè)的組件
前端需要根據(jù)后端返回的菜單列表去動(dòng)態(tài)的展示菜單列表:
并且為每個(gè)菜單列表項(xiàng)注冊(cè)對(duì)應(yīng)的路由:
在views/main文件夾下創(chuàng)建所有的頁(yè)面(component)
在router/main文件夾下創(chuàng)建每個(gè)頁(yè)面對(duì)應(yīng)的路由對(duì)象(此時(shí)只是先配置好路由path和組件component的映射關(guān)系,還沒(méi)有注冊(cè)路由,后續(xù)會(huì)根據(jù)后端返回的用戶菜單表數(shù)據(jù)(userMenus)動(dòng)態(tài)的去注冊(cè)路由)
根據(jù)用戶的角色role.id向后端發(fā)送請(qǐng)求,拿到當(dāng)前登錄用戶的userMenus菜單
根據(jù)userMenus生成對(duì)應(yīng)的routes
1)先拿到項(xiàng)目中所有組件的路由對(duì)象route放到allRoutes數(shù)組中
2)再遞歸遍歷userMenus數(shù)組的每一項(xiàng)(menu),將滿足menu.url === route.path條件的menu放到routes數(shù)組中
遍歷routes數(shù)組,把數(shù)組中的每一個(gè)route通過(guò)router.addRoute('main', route),動(dòng)態(tài)注冊(cè)到main路由對(duì)象的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">后臺(tái)管理系統(tǒng)
</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"><!-- 有二級(jí)菜單的一級(jí)菜單
--><template v
-if="item.type === 1"><!-- 一級(jí)菜單
--><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"><!-- 二級(jí)菜單
--><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
><!-- 沒(méi)有二級(jí)菜單的一級(jí)菜單
--><template v
-else-if="item.type === 2"><!-- 一級(jí)菜單
--><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
>
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的Vue权限控制——动态注册路由的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。