vue使用動態(tài)添加路由(router.addRoutes)加載權(quán)限側(cè)邊欄的方式
工作中我們經(jīng)常會遇到這種需求,后臺定義用戶的權(quán)限數(shù)據(jù),前端進行獲取,并渲染在側(cè)邊欄導(dǎo)航上,不同權(quán)限的用戶看到的側(cè)邊欄是不同的。
即前端渲染的數(shù)據(jù)是隨著后臺的改變而改變的,做到真正的前后端分離。
一、拿到需要動態(tài)添加的路由表
我們的思路是:
登錄(login,所有人均可見)--------->登錄成功,獲取權(quán)限-------->權(quán)限不同,側(cè)邊欄的數(shù)據(jù)展示不同
先定義一份公共的路由表,里面僅有一些公共的路由,如 login
獲取到權(quán)限后,我們根據(jù)權(quán)限,得到需要動態(tài)添加的路由表,把這份路由表動態(tài)添加到router中即可。
通過查閱網(wǎng)上的資料,論壇等我總結(jié)出了2條方式,分別是前端主導(dǎo)和后臺主導(dǎo)。
(1)前端主導(dǎo)
何謂前端主導(dǎo)?就是在整個權(quán)限方面,主體是定義在前端。前端需要提前定義一份完整的路由權(quán)限表,后臺的作用僅僅是返回當前用戶的權(quán)限列表,把獲取到的權(quán)限表比對完整的權(quán)限表,那么得到一份新的路由權(quán)限表拿去渲染。
這里需要注意的是,為什么不直接把后臺返回的權(quán)限列表拿去渲染,而是需要通過比對,才得出權(quán)限表?
因為后臺返回的僅僅只是字符串!
我們在使用vue-router定義路由的時候,是需要導(dǎo)入該路由對應(yīng)的component的,如下所示, component是必須引入的,而后臺返回給我們的數(shù)據(jù)是不會帶component對應(yīng)的組件的。
import Login from './views/Login.vue'
let publicRoutes = [
{
path: '/login',
name: 'login',
component: Login
}
]因此我們可以在前端通過提前定義一份全部的,完整的路由表,把后臺傳的數(shù)據(jù)當參考使用,從而得出一份路由權(quán)限表。
舉個例子:
在前端定義的完整權(quán)限表:
import Order from './components/orderCompontents/order.vue'
import OrderList from './components/orderCompontents/orderList.vue'
import ProductManage from './components/orderCompontents/productManage.vue'
import ProductionList from './components/orderCompontents/productionList.vue'
import ReviewManage from './components/orderCompontents/reviewManage.vue'
import ReturnGoods from './components/orderCompontents/returnGoods.vue'
const allroutes = [
{
path: '/order',
title: 'order-manage',
component: Order,
meta: {
name: '訂單管理'
},
children: [
{
path: '/order-list',
title: 'order-list',
component: OrderList,
meta: {
name: '訂單列表'
}
},
{
path: '/product',
title: 'product-manage',
component: ProductManage,
meta: {
name: '生產(chǎn)管理'
},
children: [
{
path: '/product-list',
title: 'product-list',
component: ProductionList,
meta: {
name: '生產(chǎn)列表'
}
},
{
path: '/review-manage',
title: 'review-manage',
component: ReviewManage,
meta: {
name: '審核管理'
}
}
]
},
{
path: '/return-goods',
title: 'return-goods',
component: ReturnGoods,
meta: {
name: '退貨管理'
}
}
]
}
]后臺傳輸過來的數(shù)據(jù):
{
"code": 0,
"message": "獲取權(quán)限成功",
"data": [
{
"name": "訂單管理",
"children": [
{
"name": "訂單列表"
},
{
"name": "生產(chǎn)管理",
"children": [
{
"name": "生產(chǎn)列表"
}
]
},
{
"name": "退貨管理"
}
]
}
]
}我們對比這兩個數(shù)據(jù)的name屬性,就能很輕易的過濾出一份路由權(quán)限表。再通過router.addRoutes()動態(tài)添加進路由即可。
(2)后臺主導(dǎo)
前面一種方式比較簡單,前端定義好,后臺傳過來進行比對即可,但是缺點也是很明顯。
如果后臺傳遞的權(quán)限名稍稍做一些改動,那么前端就匹配不到相應(yīng)的路由了。也就是改一個權(quán)限名,前端后臺需要一起改。。有點不太符合前后端徹底分離的思想。
我們想要的是,只改后臺,那么前端會根據(jù)接收的數(shù)據(jù)自動變化! 怎么解決這個問題呢? 那就是用后臺主導(dǎo)思想。
思路如下:
路由表不在前端進行比對,后臺對用戶的權(quán)限進行比對,返回給前端一個比對好的路由表,且返回的路由表需要有如下字段:
{
"data": {
"router": [
{
"path": "",
"redirect": "/home",
},
{
"path": "/home",
"component": "Home",
"name": "Home",
"meta": {
"title": "首頁",
"icon": "example"
},
"children": [
{
"path": "/xitong",
"name": "xitong",
"component": "xitong/xitong",
"meta": {
"title": "系統(tǒng)",
"icon": "table"
}
}
]
},
{
"path": "*",
"redirect": "/404",
"hidden": true
}
]
}
}注意其中的component字段,他是字符串,我們需要把這個字符串轉(zhuǎn)化為我們前端定義的組件!
function filterRouter(routers) { // 遍歷后臺傳來的路由字符串,轉(zhuǎn)換為組件對象
const accessedRouters = routers.filter(route => {
if (route.component) {
if (route.component === 'Home') { // Home組件特殊處理
route.component = Home
} else {
route.component = _import(route.component)
}
}
if (route.children && route.children.length) {
route.children = filterRouter(route.children)
}
return true
})
return accessedRouters
}這個函數(shù)的主要作用就是把后臺傳過來的字符串型的component轉(zhuǎn)化為真正的組件
其中_import()函數(shù)的定義如下:
function _import (file) {
return () => import('@/components/views/' + file + '.vue')
}通過異步加載組件,去請求該組件
其中的路徑需要大家根據(jù)自己文件的路徑去修改。
這種方法最重要的一點就是,后臺傳遞的component實際存放的是路徑!前端根據(jù)這個路徑去找到這個組件并異步加載組件。
最終執(zhí)行結(jié)束后,filterRouter返回的就是一份路由權(quán)限列表,里面的component也有了引用。
這種方法的好處在于,前端的所有權(quán)限路由數(shù)據(jù)都來自于后臺,只要路徑不改,后臺任意修改數(shù)據(jù),前端均會自動變化。
注意: 如果后臺修改的是字段 “component ” 的時候,前端需要修改文件名進行配合,若是其他修改前端則均無需任何更改。
二、渲染數(shù)據(jù)到側(cè)邊欄
通過 (一) 的方式我們可以拿到一份要渲染的路由表,我是存到了vuex中,然后在sideBar頁面中拿出來,渲染。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- vue3.0+element Plus實現(xiàn)頁面布局側(cè)邊欄菜單路由跳轉(zhuǎn)功能
- Vue3實現(xiàn)簡約型側(cè)邊欄的示例代碼
- Vue3點擊側(cè)邊導(dǎo)航欄完成切換頁面內(nèi)組件全過程(WEB)
- Vue-element-admin平臺側(cè)邊欄收縮控制問題
- vue框架實現(xiàn)將側(cè)邊欄完全隱藏
- vue實現(xiàn)側(cè)邊定位欄
- VuePress 側(cè)邊欄的具體使用
- 如何利用Vue3管理系統(tǒng)實現(xiàn)動態(tài)路由和動態(tài)側(cè)邊菜單欄
- vue elementui簡易側(cè)拉欄的使用小結(jié)
相關(guān)文章
vue template當中style背景設(shè)置不編譯問題
這篇文章主要介紹了vue template當中style背景設(shè)置不編譯問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04
vue3組件的v-model:value與v-model的區(qū)別解析
在Vue3中,v-model和v-model:value都是用于實現(xiàn)雙向數(shù)據(jù)綁定的語法糖,但v-model:value提供了更顯式和靈活的綁定方式,允許你明確指定綁定的屬性名和事件名,它們的主要區(qū)別在于默認行為、靈活性、多模型綁定和使用場景,感興趣的朋友一起看看吧2025-02-02
vue-element-admin中node-sass換成dart-sass,安裝依賴報code?128多種問題的解決
這篇文章主要介紹了vue-element-admin中node-sass換成dart-sass,安裝依賴報code?128多種問題的解決方法,本文給大家分享問題原因分析及解決方法,需要的朋友可以參考下2023-02-02
vue3的setup語法如何自定義v-model為公用hooks
這篇文章主要介紹了vue3的setup語法如何自定義v-model為公用hooks,文章分為兩個部分介紹,簡單介紹vue3的setup語法如何自定義v-model和如何提取v-model語法作為一個公用hooks2022-07-07

