一个React包装器的应用 - 权限管理

    xiaoxiao2025-11-29  21

    在我们的应用中,每个按钮都有个权限点,前端通过接口的方式取得此用户的权限点列表,再来决定按钮是否显示。假設我们权限点列表取得后存在window.globals.permissions。

    传统的方式可以在redner的时候,判断用户是否有此权限,在来决定按钮是否显示。例如:

    class Page1 extend React.Component { render() { const {create, update} = window.globals.permissions; return ( {create && <Button>Create Project</Button>} {update && <Button>Update Project</Button>} ); } }

    如果现在又有个页面叫做Page2,又要再写类似的判断在Page2里面。再者如果需求改变成:"当用户没有权限的时候,按钮设定为disabled"。这样又要把分散再各页面的权限管理逻辑,通通修改一变,如:

    class Page1 extend React.Component { render() { const {create, update} = window.globals.permissions; return ( {<Button disabled={!create}>Create Project</Button>} {<Button disabled={!update}>Update Project</Button>} ); } }

    这显然不是一个优雅的解法。其实用户是否有某按钮的权限,只需要关心權限點的名稱,能不能这样写?

    class Page1 extend React.Component { render() { return ( {<Button auth="create">Create Project</Button>} {<Button auth="update">Update Project</Button>} ); } }

    在按钮的地方,只要指定权限点名称就好了。要判断window.globals.permissions和是否隐藏/disabled就交由包装器统一处理即可。接下来我们看一下包装器的部份:

    export default function injectAuth(component) { const checkAuth = (props) => { let {auth} = props; // No Auth required if(auth == null) { return true; } return windows.globals.permissions[auth]; } let WrappedClass = class extends component { render() { if(checkAuth(this.props)) { return super.render(); } else { const noAuthType = this.props.noAuthType || 'hidden'; if(noAuthType === 'hidden') { return null; } else if(noAuthType === 'disabled') { // React doesn't allow to modify props like this.prpos.disabled=ture // Should clone the element to with inital props // See: http://stackoverflow.com/questions/32370994/how-to-pass-props-to-this-props-children return React.cloneElement(super.render(), {disabled:true}); } else { throw new Error('noAuthType必须是hidden或disabled'); } } } } return WrappedClass; }

    injectAuth(component)方法的入参是组件的Class,这里的例子是Button。injectAuth将产生了一个新的Class,这个Class继承了Button Class,所以原本Button组件的行为都会被保留下来。

    内部再调用checkAuth方法,检查此外部传进来的auth property是否在windows.globals.permissions是存在的。如果权限检查通过,就直接返回原本Button的render结果:

    return super.render();

    如果权限检查不通过,則根据noAuthType来决定是要隐藏或者disabled组件。

    OK, 有了这个injector后,在我们可以在组件本身都统一置入这样的功能:

    class Button {  ... } export default injectAuth(Button);

    这样在个页面使用组件的时候,就不用一一的去写injectAuth的带代码了。

    相关资源:用于ReactJS的MapboxGLJavascript包装器
    最新回复(0)