版權聲明:本文為博主原創文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/qq_31906983/article/details/89054798
工作中我們經常會遇到這種需求,后台定義用戶的權限數據,前端進行獲取,並渲染在側邊欄導航上,不同權限的用戶看到的側邊欄是不同的。即前端渲染的數據是隨着后台的改變而改變的,做到真正的前后端分離。
一、拿到需要動態添加的路由表
我們的思路是:
登錄(login,所有人均可見)--------->登錄成功,獲取權限-------->權限不同,側邊欄的數據展示不同
先定義一份公共的路由表,里面僅有一些公共的路由,如 login
獲取到權限后,我們根據權限,得到需要動態添加的路由表,把這份路由表動態添加到router中即可。
通過查閱網上的資料,論壇等我總結出了2條方式,分別是前端主導和后台主導。
(1)前端主導
何謂前端主導?就是在整個權限方面,主體是定義在前端。前端需要提前定義一份完整的路由權限表,后台的作用僅僅是返回當前用戶的權限列表,把獲取到的權限表比對完整的權限表,那么得到一份新的路由權限表拿去渲染。
這里需要注意的是,為什么不直接把后台返回的權限列表拿去渲染,而是需要通過比對,才得出權限表?
因為后台返回的僅僅只是字符串!
我們在使用vue-router定義路由的時候,是需要導入該路由對應的component的,如下所示, component是必須引入的,而后台返回給我們的數據是不會帶component對應的組件的。
import Login from './views/Login.vue'
let publicRoutes = [
{
path: '/login',
name: 'login',
component: Login
}
]
因此我們可以在前端通過提前定義一份全部的,完整的路由表,把后台傳的數據當參考使用,從而得出一份路由權限表。
舉個例子:
在前端定義的完整權限表:
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: '生產管理'
},
children: [
{
path: '/product-list',
title: 'product-list',
component: ProductionList,
meta: {
name: '生產列表'
}
},
{
path: '/review-manage',
title: 'review-manage',
component: ReviewManage,
meta: {
name: '審核管理'
}
}
]
},
{
path: '/return-goods',
title: 'return-goods',
component: ReturnGoods,
meta: {
name: '退貨管理'
}
}
]
}
]
后台傳輸過來的數據:
{
"code": 0,
"message": "獲取權限成功",
"data": [
{
"name": "訂單管理",
"children": [
{
"name": "訂單列表"
},
{
"name": "生產管理",
"children": [
{
"name": "生產列表"
}
]
},
{
"name": "退貨管理"
}
]
}
]
}
我們對比這兩個數據的name屬性,就能很輕易的過濾出一份路由權限表。再通過router.addRoutes()動態添加進路由即可。
(2)后台主導
前面一種方式比較簡單,前端定義好,后台傳過來進行比對即可,但是缺點也是很明顯。如果后台傳遞的權限名稍稍做一些改動,那么前端就匹配不到相應的路由了。也就是改一個權限名,前端后台需要一起改。。有點不太符合前后端徹底分離的思想。我們想要的是,只改后台,那么前端會根據接收的數據自動變化! 哈哈哈,怎么解決這個問題呢? 那就是用后台主導思想。
思路如下:
路由表不在前端進行比對,后台對用戶的權限進行比對,返回給前端一個比對好的路由表,且返回的路由表需要有如下字段:
{
"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": "系統",
"icon": "table"
}
}
]
},
{
"path": "*",
"redirect": "/404",
"hidden": true
}
]
}
}
注意其中的component字段,他是字符串,我們需要把這個字符串轉化為我們前端定義的組件!
function filterRouter(routers) { // 遍歷后台傳來的路由字符串,轉換為組件對象
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
}
這個函數的主要作用就是把后台傳過來的字符串型的component轉化為真正的組件
其中_import()函數的定義如下:
function _import (file) {
return () => import('@/components/views/' + file + '.vue')
}
通過異步加載組件,去請求該組件
其中的路徑需要大家根據自己文件的路徑去修改。
這種方法最重要的一點就是,后台傳遞的component實際存放的是路徑!前端根據這個路徑去找到這個組件並異步加載組件。
最終執行結束后,filterRouter返回的就是一份路由權限列表,里面的component也有了引用。
這種方法的好處在於,前端的所有權限路由數據都來自於后台,只要路徑不改,后台任意修改數據,前端均會自動變化。
二、渲染數據到側邊欄
通過 (一) 的方式我們可以拿到一份要渲染的路由表,我是存到了vuex中,然后在sideBar頁面中拿出來,渲染。
————————————————
版權聲明:本文為CSDN博主「上條當楊」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_31906983/article/details/89054798
