Vue实现按钮级权限方案(2)

const filterPermissionRoutes = (routes, cb) => { // 可能父路由没有设置requireOps 需要根据子路由确定父路由的requireOps routes.forEach(route => { if (route.children) { route.children = filterPermissionRoutes(route.children, cb) if (!route.meta.requireOps) { const hasNoPermission = route.children.some(child => child.meta.requireOps === null) // 如果子路由中存在不需要权限控制的路由,则跳过 if (!hasNoPermission) { route.meta.requireOps = [].concat(...route.children.map(child => child.meta.requireOps)) } } } }) return cb(routes) }

然后根据操作列表对权限路由进行过滤

let operations = null // 从后端获取后更新它 const hasOp = opcode => operations ? operations.some(op => op.opcode === opcode) : false const proutes = filterPermissionRoutes(permissionRoutes, routes => routes.filter(route => { const requireOps = route.meta.requireOps if (requireOps) { return requireOps.some(hasOp) } return true })) // 动态添加路由 router.addRoutes(proutes)

函数式组件控制局部权限

这个组件实现很简单,根据传入的操作码进行权限判断,若通过则返回插槽内容,否则返回null。另外,为了统一风格,支持一下 root 属性,表示组件的根节点

const AccessControl = { functional: true, render (h, { data, children }) { const attrs = data.attrs || {} // 如果是root,直接透传 if (attrs.root !== undefined) { return h(attrs.root || 'div', data, children) } if (!attrs.opcode) { return h('span', { style: { color: 'red', fontSize: '30px' } }, '请配置操作码') } const opcodes = attrs.opcode.split(',') if (opcodes.some(hasOp)) { return children } return null } }

动态生成权限菜单

以ElementUI为例,由于动态渲染需要进行递归,如果以文件组件的形式会多一层根组件,所以这里直接用render function简单写一个示例,可以根据自己的需求改造

// 权限菜单组件 export const PermissionMenuTree = { name: 'MenuTree', props: { routes: { type: Array, required: true }, collapse: Boolean }, render (h) { const createMenuTree = (routes, parentPath = '') => routes.map(route => { // hidden: 为true时当前菜单和子菜单都不显示 if (route.hidden === true) { return null } // 子路径处理 const fullPath = route.path.charAt(0) === 'https://www.jb51.net/' ? route.path : `${parentPath}/${route.path}` // visible: 为false时不显示当前菜单,但显示子菜单 if (route.visible === false) { return createMenuTree(route.children, fullPath) } const title = route.meta.title const props = { index: fullPath, key: route.path } if (!route.children || route.children.length === 0) { return h( 'el-menu-item', { props }, [h('span', title)] ) } return h( 'el-submenu', { props }, [ h('span', { slot: 'title' }, title), ...createMenuTree(route.children, fullPath) ] ) }) return h( 'el-menu', { props: { collapse: this.collapse, router: true, defaultActive: this.$route.path } }, createMenuTree(this.routes) ) } }

接口的权限控制

我们一般用axios,这里只需要在axios封装的基础上加几行代码就可以了,axios封装花样多多,这里简单示例

const ajax = axios.create(/* config */) export default { post (url, data, opcode, config = {}) { if (opcode && !hasOp(opcode)) { return Promise.reject(new Error('没有操作权限')) } return ajax.post(url, data, { /* config */ ...config }).then(({ data }) => data) }, // ... }

到这里,这个方案差不多就完成了,权限配置的可视化可以根据操作列表中的 routeName 来做,将操作与权限路由一一对应,在  中有一个简单实现

总结

以上所述是小编给大家介绍的Vue实现按钮级权限方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/301934cedb9fd366b379a6e4ce59bbd2.html