使用React HOC优雅得实现分层权限的路由

废话少说,直接看需求:

假设某应用中有如下三个页面:javascript

    登录页----Home.jsx
    页面A----PageA.jsx
    页面B----PageB.jsx

有如下三种用户:java

    游客(未登陆)---只能访问登录页
    普通用户(已登录)---能访问登录页及页面A
    管理员(已登录)---能访问全部页面

具体需求以下:react

  • 游客访问除登录页之外的页面时自动跳到登录页。
  • 普通用户访问页面B时页面显示无权限访问

分析需求能够获得游客、会员、管理员的权限逐层递增的。管理员的权限范围包含普通用户的权限范围,普通用户的权限范围包含游客权限范围。

因此首先将是否登录做为第一层权限:react-router

withUserPermission.jsx代码以下app

import React from 'react';
import { Redirect } from 'react-router-dom';
import { getUser } from '@/user.js';    // 判断是否已登录用户

export default Wrapper => hocProps => {
    const { component: Component, ...rest } = hocProps;

    const user = getUser();

    return (
        <Wrapper {...rest} component={ props => {
            return user
                ? <Component {...props} />
                : <Redirect to="/login" />  //  跳转到登录页
        } } />
    );
}

复制代码

而后在第二层权限,判断是否具备管理员权限: withAdminPermission.jsx代码以下dom

import React from 'react';
import { getRole } from '@/user.js';    // 获取用户角色

export default Wrapper => hocProps => {
    const { component: Component, ...rest } = hocProps;

    const hasPermission = (getRole() === 'admin') ;

    return (
        <Wrapper {...rest} component={ props => {
            return hasPermission
                ? <Component {...props} />
                : <h1>无权限访问</h1>
        } } />
    );
}

复制代码

使用这两个高阶组件,封装Routespa

PrivateRoutes.js代码以下rest

import { Route } from 'react-router-dom';
import withUserPermission from './withUserPermission';
import withAdminPermission from './withAdminPermission';

export const UserRoute = withUserPermission(Route);
export const AdminRoute = withUserPermission(withAdminPermission(Route));   // 从外向内提高权限
复制代码

下面能够使用这两个封装好的Route组件,实现上面的需求:code

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { UserRoute, AdminRoute } from './PrivateRoutes';

import PageLogin from 'views/PageLogin';
import PageA from 'views/PageA';
import PageB from 'views/PageB';

export default () => (
    <Router>
        <Route path='/login' component={PageLogin} />
        <UserRoute path='/pageA' component={PageA} />
        <AdminRoute path='/pageB' component={PageB} />
    </Router>
);
复制代码
相关文章
相关标签/搜索