隐藏和显示菜单核心 UI

Hide and Display menu Core UI

我在我的应用程序中集成了模板 Core UI

重定向在 _nav.js 上配置,如图所示:

我想问是否可以根据这种情况隐藏或显示菜单?

例如:根据条件显示 Public Student 和隐藏 Manage Convention

菜单定义在_nav.js

export default [
  {
    _tag: 'CSidebarNavTitle',
    _children: ['Menu'],
  },
  {
    _tag: 'CSidebarNavItem',
    name: 'Public Space',
    to: '/home',
  }, // ...
  {
    _tag: 'CSidebarNavItem',
    name: 'Manage Convention',
    to: '/manageConvention',
  }  // ...
]

然后,这个数组在 TheSidebar.js

上被调用
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { CCreateElement, CSidebar, CSidebarBrand, CSidebarNav, CSidebarNavDivider, CSidebarNavTitle, CSidebarMinimizer, CSidebarNavDropdown, CSidebarNavItem } from '@coreui/react'

import CIcon from '@coreui/icons-react'

// sidebar nav config
import navigation from './_nav'

const TheSidebar = () => {
  const dispatch = useDispatch()
  const show = useSelector(state => state.sidebarShow)

  return (
    <CSidebar
      show={show}
      onShowChange={(val) => dispatch({type: 'set', sidebarShow: val })}
    >
      <CSidebarBrand className="d-md-down-none" to="/">
        <CIcon
          className="c-sidebar-brand-full"
          name="logo-negative"
          height={35}
        />
        <CIcon
          className="c-sidebar-brand-minimized"
          name="sygnet"
          height={35}
        />
      </CSidebarBrand>
      <CSidebarNav>

        <CCreateElement
          items={navigation}
          components={{
            CSidebarNavDivider,
            CSidebarNavDropdown,
            CSidebarNavItem,
            CSidebarNavTitle
          }}
        />
      </CSidebarNav>
      <CSidebarMinimizer className="c-d-md-down-none"/>
    </CSidebar>
  )
}

export default React.memo(TheSidebar)

任何建议都会appreciated.Big谢谢。

阅读您的评论,您可以调用 API 来检查授权(最好是在登录后)并将其保存到状态。您可以像我在下面所做的那样将其用作标志:

尝试将下面第一行的 true 更改为 false

const getWorldAccess = () => true;//Call API for user access rights here and save it to a state

const World = () => <div>World</div>;

const Hello = () => {
    return (
      <div>Hello {getWorldAccess() && <World />}</div>
    );//replace getWorldAccess() with a state variable (you don't want to call API infinitely)
}

ReactDOM.render( <
  Hello / > ,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

您可以在 TheSidebar.js 中使用子组件 class SidebarChild 来精确确定您想要的条件。

然后,注入<CSidebar >

并且不要忘记使用常量 const SBChild = connect()(SidebarChild) 以便能够在 <CSidebar >.

中调用 SBChild

希望能有所帮助。

在组件中,CSidebar 只需将 minimize 的值设置为 true

您可以根据需要的条件过滤TheSideBar.js中的_nav.js数组。这将隐藏它,使其不显示在侧边栏中。您将必须知道要删除的项目的索引。

我认为这是对您问题的最佳回答。 首先,您必须根据以下结构划分 _nav.js 文件中的项目。 (这允许根据用户级别导出导航栏项目)。

import React from 'react'
import CIcon from '@coreui/icons-react'

var navStaff = { 
 items: [
    {
      _tag: 'CSidebarNavItem',
      name: 'Dashboard',
      to: '/dashboard',
      icon: <CIcon name="cil-speedometer" customClasses="c-sidebar-nav-icon"/>,
    }
 ]
};

var navAdmin = {
  items: [
    {
      _tag: 'CSidebarNavItem',
      name: 'Dashboard',
      to: '/dashboard',
      icon: <CIcon name="cil-speedometer" customClasses="c-sidebar-nav-icon"/>,
    },
    {
      _tag: 'CSidebarNavTitle',
      _children: ['USERS']
    },
    {
      _tag: 'CSidebarNavItem',
      name: 'Users',
      to: '/users',
      icon: 'cil-people',
    }
  ]
};

export {navStaff, navAdmin };

那么您的 TheSidebar.js 应该看起来像这样,用于在导航栏中允许不同的内容。如果你愿意,你可以使用本地存储来只允许登录的用户类型分配选定的导航栏。

import React, { lazy, useState, useEffect, useRef} from 'react'
import { useSelector, useDispatch } from 'react-redux'
import {
  CCreateElement,
  CSidebar,
  CSidebarBrand,
  CSidebarNav,
  CSidebarNavDivider,
  CSidebarNavTitle,
  CNavItem,
  CProgress,
  CSidebarMinimizer,
  CSidebarNavDropdown,
  CSidebarNavItem,
} from '@coreui/react'
import CIcon from '@coreui/icons-react'

// sidebar nav config
import {navStaff, navAdmin} from './_nav'

const TheSidebar = () => {

  console.log(navStaff)

  const dispatch = useDispatch()
  const show = useSelector(state => state.sidebarShow);

  return (
    <CSidebar
      show={show}
      unfoldable
      onShowChange={(val) => dispatch({type: 'set', sidebarShow: val })}
    >
      <CSidebarBrand className="d-md-down-none" to="/">
        <CIcon
          className="c-sidebar-brand-minimized"
          name="sygnet"
          height={35}
        />
      </CSidebarBrand>
      <CSidebarNav>

        <CCreateElement
          items={navAdmin.items}
          components={{
            CSidebarNavDivider,
            CSidebarNavDropdown,
            CSidebarNavItem,
            CSidebarNavTitle
          }}
        />

        <CSidebarNavDivider />
      </CSidebarNav>
      <CSidebarMinimizer className="c-d-md-down-none"/>
    </CSidebar>
  )
}

export default React.memo(TheSidebar)

希望您能得到您需要的答案。谢谢

我知道这是一个老问题但是:

我认为最简单的解决方案是在 _nav.js 中为每个“CNavItem”添加一个 meta 道具。 15=]

//_nav.js

const _nav = [    
       {
        component: CNavItem,
        name: 'Locations',
        to: '/location',
        meta: { role: ['Admin', 'Recruiter'] },
        icon: <CIcon icon={cilLocationPin} customClassName="nav-icon" />
      },
]

辅助函数

export default function hasAccess(userRole, roles) {
    if (Array.isArray(userRole)) {
        return roles.some((r) => userRole.map((item) => item.toLowerCase()).includes(r.toLowerCase()))
    } else {
        return roles.map((item) => item.toLowerCase()).includes(userRole.toLowerCase())
    }
}

之后,在 AppSidebarNav.js 组件内,检查导航项是否至少包含一个用户角色。如果有就渲染,否则不渲染。

userRole 在这种情况下,它是从 redux 存储返回的。如何获得登录用户角色取决于您。

//AppSidebarNav.js

export const AppSidebarNav = ({ items }) => {
  const userRole = useSelector((state) => state.user.role)

  {...}

  const navItem = (item, index) => {
    const { component, name, badge, icon, meta, ...rest } = item
    const Component = component
    return (

      hasAccess(userRole, item.meta?.role || []) && <Component

        {...(rest.to &&
          !rest.items && {
          component: NavLink,
        })}
        key={index}
        {...rest}
      >
        {navLink(name, icon, badge)}
      </Component>
    )
  }
 
 
 {...}

  return (
    <React.Fragment>
      {items &&
        items.map((item, index) => (item.items ? (navGroup(item, index)) : navItem(item, index)))}
    </React.Fragment>
  )
}