权限系统
isdream-vue-admin 提供了灵活的权限管理机制,支持路由级权限和按钮级权限。
权限模式
在 src/config/index.ts 中通过 routesHandlerOptions.setupRoutesType 配置权限模式:
ts
import type { RouteMeta } from 'vue-router'
import type { StorageConfig } from '@/storage'
import type { ServiceTokenConfig } from '@/service'
import type { RoutesHandlerOptions } from '@/router/useRoutesHandler/types'
import { readonly } from 'vue'
export type DefaultRouteMeta = Required<
Pick<
RouteMeta,
| 'keepAlive'
| 'hiddenInMenu'
| 'hiddenInBread'
| 'needLoading'
| 'needToken'
| 'needRouteHistory'
>
>
interface StoreConfig {
userMenuStorage: boolean
userPermissionsStorage: boolean
}
export interface AppConfig {
storeConfig: StoreConfig
storageConfig: StorageConfig
serviceTokenConfig: ServiceTokenConfig
needKeepAlive: boolean
routerHistory: 'Hash' | 'HTML5'
defaultRouteMeta: DefaultRouteMeta
routesHandlerOptions: RoutesHandlerOptions
routeMainName: string
routeLoginName: string
baseUrlApi: string
baseUrlFile: string
}
const viteEnv = import.meta.env
const config: Readonly<AppConfig> = {
// store/user
storeConfig: {
// storage是否存储userMenu
userMenuStorage: false,
// storage是否存储userPermissions
userPermissionsStorage: false
},
// storage
storageConfig: {
prefix: 'isdream',
expires: 7 * 24 * 60 * 60 * 1000,
version: 1
},
// service
serviceTokenConfig: {
position: 'headers',
key: 'Authorization',
value: 'Bearer TOKEN',
expires: 7 * 24 * 60 * 60 * 1000
},
// router
routerHistory: 'Hash',
// `route.component`需要使用keepAlive
needKeepAlive: true,
defaultRouteMeta: {
// 使用KeepAlive进行缓存
keepAlive: true,
hiddenInMenu: false,
hiddenInBread: false,
// router/guard
needLoading: false,
needToken: true,
needRouteHistory: true
},
// router/routes/index `routesHandler`
routesHandlerOptions: {
// 可通过 (store/user `setUserMenu`) 重设权限菜单
// `all` 添加全部路由
// `roleMenu` 匹配roleMenu,可以改变userMenu名称、层级、顺序等
// `permissions` 匹配permissions,不能改变userMenu名称、层级、顺序等
setupRoutesType: 'roleMenu',
// router.addRoute(`addRouteParentName`, [])
addRouteParentName: '__ROUTE_TEMP_NAME',
// 路由扁平化,只注册最后一层route,性能比较高。(但父级route不会注册, 缓存路由较深时推荐使用)
flatRoutes: true
},
// route name
routeMainName: '__ROUTE_MAIN_NAME',
routeLoginName: '__ROUTE_LOGIN_NAME',
// .env
baseUrlApi: viteEnv.VITE_BASE_URL_API,
baseUrlFile: viteEnv.VITE_BASE_URL_FILE
}
config.routesHandlerOptions.addRouteParentName = config.routeMainName
export const appConfig = readonly(config)
export default appConfig全量注册(all)
注册全部路由,不做权限过滤。适用于开发阶段或不需权限控制的场景。
typescript
routesHandlerOptions: {
setupRoutesType: 'all'
}角色菜单匹配(roleMenu)
根据后端返回的角色菜单匹配路由,可以自定义菜单名称、层级、顺序。
typescript
routesHandlerOptions: {
setupRoutesType: 'roleMenu'
}通过用户 Store 设置角色菜单:
typescript
import { useStores } from '@/store'
const { user } = useStores()
// 设置角色菜单数据
user.setRoleMenu(menuData)权限标识匹配(permissions)
根据权限字符串匹配路由,无法改变菜单名称、层级和顺序。
typescript
routesHandlerOptions: {
setupRoutesType: 'permissions'
}通过用户 Store 设置权限:
typescript
import { useStores } from '@/store'
const { user } = useStores()
// 设置用户权限列表
user.setUserPermissions(['dashboard', 'user:list', 'user:create'])路由级权限
动态路由由 src/router/useRoutesHandler/ 处理。处理流程:
- 读取
src/router/routes/examples/下的所有路由模块 - 根据
setupRoutesType配置过滤路由 - 动态添加到路由实例
路由定义示例:
typescript
// src/router/routes/examples/components.ts
export default {
path: '/components',
name: 'Components',
meta: {
title: '组件',
needToken: true
},
children: [...]
}按钮级权限
使用 v-auth 指令控制按钮级权限:
ts
import type { Directive } from 'vue'
import { checkAuth } from '@/utils'
/*
const permission = 'test'
v-auth:test
v-auth="permission"
*/
export const auth: Directive<HTMLElement, string | undefined> = {
mounted(el, binding) {
const { value, arg } = binding
const permission = value ?? arg
if (!permission) {
return
}
if (!checkAuth(permission)) {
el.remove()
}
}
}使用方式
支持两种写法:
vue
<!-- 通过 v-model 绑定权限标识 -->
<el-button v-auth="'user:delete'">删除</el-button>
<!-- 通过指令参数绑定权限标识 -->
<el-button v-auth:userDelete>删除</el-button>无权限时元素会从 DOM 中移除。
路由守卫
项目内置 6 个路由守卫:
| 守卫 | 文件 | 功能 |
|---|---|---|
useRedirect | router/guard/useRedirect.ts | 重定向到第一个叶子节点 |
useLoading | router/guard/useLoading.ts | 路由切换 loading |
useHasToken | router/guard/useHasToken.ts | Token 校验,未登录跳转登录页 |
useKeepAlive | router/guard/useKeepAlive.ts | KeepAlive 缓存管理 |
useRouteHistory | router/guard/useRouteHistory.ts | 路由历史(标签页) |
useDocumentTitle | router/guard/useDocumentTitle.ts | 页面标题 |