美文网首页
记一次给按钮加上权限的经历

记一次给按钮加上权限的经历

作者: 前端阿良古 | 来源:发表于2019-11-22 17:51 被阅读0次

需求:

给系统所有按钮加上权限控制,有权限则显示,没有则隐藏。
(顺提一下为什么不用disabled:因为本身的业务逻辑就有判断是否disbled,加权限是系统已经做了很久之后加的需求,如再用disabled会让业务逻辑有些混乱)

项目背景

项目为基于react的一个后台管理系统,使用umi+dva+antd的整一套系统性架构

前期准备

  1. 通过后端接口返回权限数据如下: 数据截图
  2. 系统登录的同时获取权限数据,并保存在sessionStorage中(下面省略请求数据的代码)
const STORE_MENUS = 'antd-menus';
updateMenus(state, action) {
  const { payload } = action;
  sessionStorage.setItem(STORE_MENUS, JSON.stringify(payload));
  return {
    ...state,
  };
},

重点来了 -- 解决历程

方案一:使用高阶组件加工一次原本的按钮
import React, { Component } from 'react';

const WrapAuth = ComposedComponent => class WrapComponent extends Component {

  // 判断是否有权限
  handleAuth = (id) => {
    const menujson = sessionStorage.getItem('antd-menus');
    if (menujson != null) {
      const menuData = JSON.parse(menujson);
      const { code, data } = menuData;
      if (code === 200 && data) {
        const { buttons } = data;
        return buttons.includes(id);
      }
    }
    return false;
  }

  render() {
    const { authority } = this.props;

    if (this.handleAuth(authority)) {
      return <ComposedComponent {...this.props} />;
    }
    return null;
  }
};

export default WrapAuth;

使用高阶组件,这里出现了一个问题,就是我们的按钮有可能使用了 antd 的 Button 组件,也有可能是 Link ,那每次要用 WrapAuth 时就需要为不同的组件各自加工一次,如:

import WrapAuth from '@/components/WrapAuth';
const WrapButton = WrapAuth(Button);
const WrapLink = WrapAuth(Link);

因为这个问题,故思考了另一种方案

方案二:写个函数式组件包装原来的按钮控制其显示与否
const WrapAuth = (props) => {

  const handleAuth = (id) => {
    const menujson = sessionStorage.getItem('antd-menus');
    if (menujson != null) {
      const menuData = JSON.parse(menujson);
      const { code, data } = menuData;
      if (code === 200 && data) {
        const { buttons } = data;
        return buttons.includes(id);
      }
    }
    return false;
  }

  const { authority, children } = props;

  return handleAuth(authority) ? {...children} : null;

};

export default WrapAuth;

如何使用

import WrapAuth from '@/components/WrapAuth';
<WrapAuth authority="906871085780005">
  <Button icon="plus" type="primary" onClick={this.handleAdd}>
    新建
  </Button>
</WrapAuth>
<WrapAuth authority="906871085840005">
   <>
    <a onClick={e => this.handleEdit(e, record.exhibitionId)}>编辑</a>
    <Divider type="vertical" />
  </>
</WrapAuth>

总结

  • 通过后端接口枚举权限id的方式虽然解决了权限控制问题,但是总感觉这种方式太粗暴,希望以后能学到更好的方式
  • 高阶组件就是个函数,它并不是一个组件,虽然用起来感觉高大上,但不是所有问题都用它解决,就以上的场景来看,简简单单写个函数式组件更好
  • 写函数式组件时,当所写组件转译之后并没有用到 react.createElement 时,可以不引入 React

相关文章

网友评论

      本文标题:记一次给按钮加上权限的经历

      本文链接:https://www.haomeiwen.com/subject/vleqwctx.html