You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何为Admin与Restaurant角色展示不同侧边栏(兼容Router v6)

React 多角色侧边栏导航与路由权限控制(兼容React Router v6)

步骤1:给路由和导航项添加权限配置

先修改路由和导航数据,加入角色权限与角色专属名称的配置:

修改 routes.js

const routes = [
  { path: '/', exact: true, name: 'Home' },
  {
    path: '/dashboard',
    name: 'Dashboard',
    element: Dashboard,
    roles: ['Admin', 'Restaurant'] // 两个角色均可访问
  },
  {
    path: '/foundation',
    name: 'Foundation',
    element: Foundation,
    roles: ['Admin'] // 仅Admin角色可访问
  },
]

修改 _nav.js

const _nav = [
  {
    component: CNavItem,
    name: 'Dashboard',
    nameByRole: { // 不同角色显示不同名称
      Restaurant: '我的仪表盘'
    },
    to: '/dashboard',
    icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />,
    badge: {
      color: 'info',
    },
    roles: ['Admin', 'Restaurant']
  },
  {
    component: CNavItem,
    name: '基础设置',
    to: '/foundation',
    icon: <CIcon icon={cilHome} customClassName="nav-icon" />,
    badge: {
      color: 'info',
    },
    roles: ['Admin']
  },
]

步骤2:侧边栏组件过滤导航项

在侧边栏组件(假设为 Sidebar.js)中,根据当前用户角色过滤并渲染导航项:

import { useSelector } from 'react-redux';
import { _nav } from './_nav';

const Sidebar = () => {
  // 从Redux store获取当前用户角色(需确保登录时已存入store)
  const currentUser = useSelector(state => state.auth.user);
  const userRole = currentUser?.role;

  // 过滤出当前角色有权限的导航项,并替换为角色专属名称
  const filteredNav = _nav
    .filter(item => !item.roles || item.roles.includes(userRole))
    .map(item => ({
      ...item,
      name: item.nameByRole?.[userRole] || item.name
    }));

  return (
    <div className="sidebar">
      {filteredNav.map((item, index) => {
        const Component = item.component;
        return (
          <Component
            key={index}
            to={item.to}
            icon={item.icon}
            badge={item.badge}
          >
            {item.name}
          </Component>
        );
      })}
    </div>
  );
};

export default Sidebar;

步骤3:路由层面的权限控制(防止直接URL访问)

创建 ProtectedRoute 组件,用于保护需要权限的路由:

import { Navigate, Outlet } from 'react-router-dom';
import { useSelector } from 'react-redux';

const ProtectedRoute = ({ allowedRoles }) => {
  const currentUser = useSelector(state => state.auth.user);
  const userRole = currentUser?.role;

  // 未登录跳转登录页
  if (!currentUser) {
    return <Navigate to="/login" replace />;
  }

  // 无权限跳转首页
  if (allowedRoles && !allowedRoles.includes(userRole)) {
    return <Navigate to="/" replace />;
  }

  return <Outlet />;
};

export default ProtectedRoute;

修改 App.js,配置嵌套路由:

import ProtectedRoute from './ProtectedRoute';
import Dashboard from './Dashboard';
import Foundation from './Foundation';

const App = () => {
  return (
    <Provider store={store}>
      <Suspense fallback={loading}>
        <Routes>
          <Route path="*" name="Home" element={<Home />} />
          <Route path="/login" name="Login Page" element={<Login />} />
          <Route path="/register" name="Register Page" element={<Register />} />
          
          {/* 受保护的路由组 */}
          <Route element={<ProtectedRoute allowedRoles={['Admin', 'Restaurant']} />}>
            <Route path="/dashboard" element={<Dashboard />} />
          </Route>
          <Route element={<ProtectedRoute allowedRoles={['Admin']} />}>
            <Route path="/foundation" element={<Foundation />} />
          </Route>
        </Routes>
      </Suspense>
      <ToastContainer></ToastContainer>
    </Provider>
  );
};

export default App;

注意事项

  • 确保登录时将用户角色(role)存入Redux store或Context中,以便组件获取
  • 若不使用Redux,可改用React Context API管理用户角色状态
  • 导航项的 nameByRole 可按需自定义,比如给Restaurant角色的Dashboard设置为“我的店铺”
  • 路由权限控制是必要的,避免用户直接通过URL访问无权限页面

内容的提问来源于stack exchange,提问作者Sabri Yaşar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:02:07