权限
- 按钮权限
- 菜单权限
- 登陆权限
权限搭建
基础准备:通过登陆获取权限去匹配权限列表中是否符合实现相关功能操作
- 后端需要提前返回当前用户的权限标识,根据产品所定义的权限规则,进行录入处理
- element-push的集成内置权限部分判断
一. 按钮权限(自定义v-显示判断)
按钮的判断涉及一个页面多个零碎业务按钮,自定义组件标识指令
/**
* 按钮权限校验
*/
export const hasPerm: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
// 「超级管理员」拥有所有的按钮权限
const { user } = useStore();
const roles = user.roles;
if (roles.indexOf('admin') >= 0) return true //
// 「其他角色」按钮权限校验
const { value } = binding;
if (value) {
const requiredPerms = value; // DOM绑定需要的按钮权限标识
const hasPerm = user.perms?.some(perm => {
return requiredPerms.includes(perm);
});
if (!hasPerm) {
el.parentNode && el.parentNode.removeChild(el);
}
} else {
throw new Error(
"need perms! Like v-has-perm=\"['sys:user:add','sys:user:edit']\""
);
}
}
};
//main引用
import * as directive from '@/directive';
app.use(directives)
//运用
v-hasPerm=['server','menu']
二. 菜单权限 , 登陆权限
路由拦截处理页面操作,刷新后进行筛选处理,路由录入进行分类,基础路由baseRoutes
和 业务权限路由 constantRoutes
// src/store/modules/permission.ts
if (jwt) {
await user.getUserInfo();
const roles = user.roles;
//此处就是去筛选权限,permission 是store的定义方法
const accessRoutes:any = await permission.generateRoutes(roles);
if (accessRoutes.length === 0) {
// 无权限的直接登出处理
removeJwt()
next({ path: '/noAuth', replace: true })
return false;
} else {
//路由添加进去跳转
accessRoutes.forEach((route: any) => {
router.addRoute(route);
});
if (to.path === '/login' && accessRoutes && accessRoutes.length > 0) {
next({ path: '/', replace: true })
} else {
next({ ...to, replace: true })
}
}
}
//src/directive/permission/index.ts
const accessedRoutes = filterAsyncRoutes(constantRoutes, roles);
export const filterAsyncRoutes = (
routes: RouteRecordRaw[],
roles: string[] ) =>
{
const accessedRouters = routes.filter(route => {
if (hasPermission(roles, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRoutes(route.children, roles)
}
return true
}
return false
})
return accessedRouters
}
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
if (route.meta && route.meta.roles) {
if (roles.indexOf('admin') >= 0) return true //
return roles.some(role => {
if (route.meta?.roles !== undefined) {
return (route.meta.roles as string[]).includes(role);
}
});
}
return false;
};