使用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>
);
複製代碼
相關文章
相關標籤/搜索