vue使用動態(tài)添加路由(router.addRoutes)加載權(quán)限側(cè)邊欄的方式
工作中我們經(jīng)常會遇到這種需求,后臺定義用戶的權(quán)限數(shù)據(jù),前端進(jìn)行獲取,并渲染在側(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)限表,后臺的作用僅僅是返回當(dāng)前用戶的權(quán)限列表,把獲取到的權(quán)限表比對完整的權(quán)限表,那么得到一份新的路由權(quán)限表拿去渲染。
這里需要注意的是,為什么不直接把后臺返回的權(quán)限列表拿去渲染,而是需要通過比對,才得出權(quán)限表?
因?yà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ù)當(dāng)參考使用,從而得出一份路由權(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)添加進(jìn)路由即可。
(2)后臺主導(dǎo)
前面一種方式比較簡單,前端定義好,后臺傳過來進(jìn)行比對即可,但是缺點(diǎn)也是很明顯。
如果后臺傳遞的權(quán)限名稍稍做一些改動,那么前端就匹配不到相應(yīng)的路由了。也就是改一個權(quán)限名,前端后臺需要一起改。。有點(diǎn)不太符合前后端徹底分離的思想。
我們想要的是,只改后臺,那么前端會根據(jù)接收的數(shù)據(jù)自動變化! 怎么解決這個問題呢? 那就是用后臺主導(dǎo)思想。
思路如下:
路由表不在前端進(jìn)行比對,后臺對用戶的權(quán)限進(jì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ù)自己文件的路徑去修改。
這種方法最重要的一點(diǎn)就是,后臺傳遞的component實(shí)際存放的是路徑!前端根據(jù)這個路徑去找到這個組件并異步加載組件。
最終執(zhí)行結(jié)束后,filterRouter返回的就是一份路由權(quán)限列表,里面的component也有了引用。
這種方法的好處在于,前端的所有權(quán)限路由數(shù)據(jù)都來自于后臺,只要路徑不改,后臺任意修改數(shù)據(jù),前端均會自動變化。
注意: 如果后臺修改的是字段 “component ” 的時候,前端需要修改文件名進(jìn)行配合,若是其他修改前端則均無需任何更改。
二、渲染數(shù)據(jù)到側(cè)邊欄
通過 (一) 的方式我們可以拿到一份要渲染的路由表,我是存到了vuex中,然后在sideBar頁面中拿出來,渲染。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- vue3.0+element Plus實(shí)現(xiàn)頁面布局側(cè)邊欄菜單路由跳轉(zhuǎn)功能
- Vue3實(shí)現(xiàn)簡約型側(cè)邊欄的示例代碼
- Vue3點(diǎn)擊側(cè)邊導(dǎo)航欄完成切換頁面內(nèi)組件全過程(WEB)
- Vue-element-admin平臺側(cè)邊欄收縮控制問題
- vue框架實(shí)現(xiàn)將側(cè)邊欄完全隱藏
- vue實(shí)現(xiàn)側(cè)邊定位欄
- VuePress 側(cè)邊欄的具體使用
- 如何利用Vue3管理系統(tǒng)實(shí)現(xiàn)動態(tài)路由和動態(tài)側(cè)邊菜單欄
- vue elementui簡易側(cè)拉欄的使用小結(jié)
相關(guān)文章
Vue?transition組件簡單實(shí)現(xiàn)數(shù)字滾動
這篇文章主要為大家介紹了Vue?transition組件簡單實(shí)現(xiàn)數(shù)字滾動示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09vuejs響應(yīng)用戶事件(如點(diǎn)擊事件)
本篇文章主要介紹了vuejs響應(yīng)用戶事件(如點(diǎn)擊),通過vuejs響應(yīng)用戶事件的技巧,具有一定的參考價值,有興趣的小伙伴們可以參考一下。2017-03-03Vue.js 2.0和Cordova開發(fā)webApp環(huán)境搭建方法
下面小編就為大家分享一篇Vue.js 2.0和Cordova開發(fā)webApp環(huán)境搭建方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02基于Vue3實(shí)現(xiàn)鼠標(biāo)滑動和滾輪控制的輪播
在這篇文章主要為大家詳細(xì)介紹了如何一步步地實(shí)現(xiàn)一個基于?Vue?3?的輪播組件,這個組件的特點(diǎn)是可以通過鼠標(biāo)滑動和滾輪來控制輪播圖的切換,感興趣的可以了解下2024-02-02Vue3中如何使用v-model高級用法參數(shù)綁定傳值
本文給大家介紹Vue3中使用v-model高級用法參數(shù)綁定傳值的相關(guān)知識,包括單個輸入框傳值和多個輸入框傳值,一個組件接受多個v-model值,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-10-10vue3中各種類型文件進(jìn)行預(yù)覽功能實(shí)例
在vue移動端項目中經(jīng)常遇到這樣的需求,對一些上傳的附件可以點(diǎn)擊之后在線預(yù)覽,所以下面這篇文章主要給大家介紹了關(guān)于vue3中各種類型文件進(jìn)行預(yù)覽功能的相關(guān)資料,需要的朋友可以參考下2021-09-09