在基于 `vue-admin-template` 實現權限管理時,通常需要結合角色權限模型和動態路由機制,以滿足不同用戶角色對頁面訪問權限的控制需求。分為路由頁面權限和按鈕權限:下面是具體實現思路的思維導圖和具體代碼流程:
0.實現邏輯思維導圖:
1. 角色權限模型設計
在權限管理中,最基礎的模型是 RBAC( 模型,即基于角色的訪問控制。系統中定義多個角色(如管理員、普通用戶等),每個角色擁有特定的權限集合,權限可以是菜單訪問權限、按鈕操作權限等。
在 `vue-admin-template` 中,可以通過擴展路由配置來實現角色權限控制。每個路由對象可以增加 `meta` 字段,用于標識該路由所需的權限角色。
```javascript
{path: '/admin',component: Layout,meta: { roles: ['admin'] },children: [{path: 'dashboard',component: () => import('@/views/dashboard/index'),meta: { roles: ['admin'] }}]
}
```
2.?動態路由機制
`vue-admin-template` 本身是一個基礎模板,不包含動態路由功能。要實現權限控制,需要引入動態路由機制。具體流程如下:
1. 用戶登錄后,向后端請求當前用戶的角色信息。
2. 根據角色信息,從前端定義的路由表中篩選出該角色可訪問的路由。
3. 使用 `router.addRoutes()` 方法將篩選后的路由添加到 Vue Router 中。
示例代碼如下:
```javascript
import { constantRoutes, asyncRoutes } from '@/router'/*** Filter asynchronous routes through permissions* @param routes* @param roles*/
export function filterAsyncRoutes(routes, roles) {const res = []routes.forEach(route => {const tmp = { ...route }if (hasPermission(roles, tmp)) {if (tmp.children) {tmp.children = filterAsyncRoutes(tmp.children, roles)}res.push(tmp)}})return res
}/*** Determine if the route requires permission* @param roles* @param route*/
function hasPermission(roles, route) {if (route.meta && route.meta.roles) {return roles.some(role => route.meta.roles.includes(role))}return true
}const state = {routes: [],addRoutes: []
}const mutations = {SET_ROUTES: (state, routes) => {state.addRoutes = routesstate.routes = constantRoutes.concat(routes)}
}const actions = {generateRoutes({ commit }, roles) {return new Promise(resolve => {let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}
}
```
3. 后端權限控制與數據庫路由表
在實際項目中,權限配置通常由后端維護,前端從接口獲取當前用戶的角色信息及可訪問的路由列表。這樣可以避免每次權限變更都需要重新發布前端代碼。
后端可以提供一個接口,例如:
```
GET /api/user/roles
```
返回示例:
```json
{"roles": ["admin", "editor"],"routes": [{"path": "/dashboard","name": "Dashboard","component": "dashboard/index","meta": {"roles": ["admin"]}}]
}
```
前端根據返回的 `routes` 字段動態生成路由表,并通過 `router.addRoutes()` 添加。
4. 按鈕權限控制
除了頁面級別的權限控制,還需要對按鈕級別的操作進行限制。通常可以通過自定義指令或組件封裝實現。
示例:自定義 `v-permission` 指令
```javascript
Vue.directive('permission', {inserted(el, binding) {const { value } = bindingconst roles = store.getters.rolesif (value && value instanceof Array && value.length > 0) {const permissionRoles = valueconst hasPermission = roles.some(role => {return permissionRoles.includes(role)})if (!hasPermission) {el.parentNode && el.parentNode.removeChild(el)}} else {throw new Error(`need roles! Like v-permission="['admin','editor']"`)}}
})
```
在模板中使用:
```html
<el-button v-permission="['admin']">刪除</el-button>
```
5. 總結
`vue-admin-template` 實現權限管理的核心在于 **角色權限模型 + 動態路由 + 按鈕權限控制**。