当前位置: 首页>前端>正文

ant design vue pro 权限 ant design pro 菜单 权限

一、React 结合 Antd 实现权限列表
  1. 引入所需相关的组件和文件,如下所示:
import React, { Component } from 'react'
import { Link, withRouter } from 'react-router-dom'
import { Menu, Icon } from 'antd'
import logo from '../../assets/images/logo.png'
import menuList from '../../config/menuConfig'
import memoryUtils from '../../utils/memoryUtils'
import './index.less'

const { SubMenu } = Menu
  1. 创建 LeftNav 左侧菜单组件,由于 LeftNav 不是路由组件,需要变为路由组件,可以使用 react-router-dom 中的 withRouterwithRouter 是一个高阶组件,包装非路由组件, 返回一个新的组件,新的组件向非路由组件传递三个属性: history/location/match,代码如下所示:
class LeftNav extends Component {}
export default withRouter(LeftNav)
  1. 我们需要先渲染左侧菜单列表,先准备了一个菜单数据的配置文件 menuConfig.js,用于动态渲染,代码如下所示:
const menuList = [
  {
    title: '首页', 
    key: '/home', 
    icon: 'home', 
    isPublic: true, 
  },
  {
    title: '商品',
    key: '/products',
    icon: 'appstore',
    children: [ 
      {
        title: '品类管理',
        key: '/category',
        icon: 'bars'
      },
      {
        title: '商品管理',
        key: '/product',
        icon: 'tool'
      },
    ]
  },

  {
    title: '用户管理',
    key: '/user',
    icon: 'user'
  },
  {
    title: '角色管理',
    key: '/role',
    icon: 'safety',
  },

  {
    title: '图形图表',
    key: '/charts',
    icon: 'area-chart',
    children: [
      {
        title: '柱形图',
        key: '/charts/bar',
        icon: 'bar-chart'
      },
      {
        title: '折线图',
        key: '/charts/line',
        icon: 'line-chart'
      },
      {
        title: '饼图',
        key: '/charts/pie',
        icon: 'pie-chart'
      },
    ]
  },

  {
    title: '订单管理',
    key: '/order',
    icon: 'windows',
  },
]

export default menuList
  1. 我们可以在 getMenuNodes 方法中传入这个配置文件,根据 menu 的数据数组生成对应的标签数组,使用 reduce() + 递归调用。判断 menuListitem 项是否有 children,如果没有,向 pre 添加 <Menu.Item>。反之,向 pre 添加 <SubMenu>。同时,查找一个与当前请求路径匹配的子 Item,如果存在, 说明当前 item 的子列表需要打开,代码如下所示:
getMenuNodes = (menuList) => {

    const path = this.props.location.pathname

    return menuList.reduce((pre, item) => {

      if (this.hasAuth(item)) {
        if (!item.children) {
          pre.push((
            <Menu.Item key={item.key}>
              <Link to={item.key}>
                <Icon type={item.icon}></Icon>
                <span>{item.title}</span>
              </Link>
            </Menu.Item>
          ))
        } else {
          const cItem = item.children.find(cItem => path.indexOf(cItem.key)===0)
          if (cItem) {
            this.openKey = item.key
          }
  
          pre.push((
            <SubMenu key={item.key} title={
              <span>
                <Icon type={item.icon}></Icon>
                <span>{item.title}</span>
              </span>
            }>
              { this.getMenuNodes(item.children) }
            </SubMenu>
          ))
        }
      }
  
      return pre
    }, [])
  }
  1. componentWillMount 中,为第一个 render() 准备数据,代码如下所示:
componentWillMount () {
    this.menuNodes = this.getMenuNodes(menuList)
  }
  1. render 中,通过 this.props.location.pathname 得到当前请求的路由路径。判断当前请求的是商品或其子路由界面,然后得到需要打开菜单项的 key。在 return 中,使用 Menu 组件。mode 是菜单类型,现在支持垂直、水平、和内嵌模式三种。theme 是 主题颜色。selectedKeys 是当前选中的菜单项 key 数组。defaultOpenKeys 是初始展开的 SubMenu 菜单项 key 数组。this.menuNodes 就是左侧菜单的数据,代码如下所示:
render () {
    let path = this.props.location.pathname
    if (path.indexOf('/product')===0) {
      path = '/product'
    }
    const openKey = this.openKey
  
    return (
      <div className="left-nav">
        <Link to="/" className="left-nav-header">
          <img src={logo} alt="logo"></img>
          <h1>React 后台</h1>
        </Link>

        <Menu
          mode="inline"
          theme="dark"
          selectedKeys={[path]}
          defaultOpenKeys={[openKey]}
        >
          { this.menuNodes }
        </Menu>
      </div>
    )
  }
  1. 在左侧菜单的数据能够正常渲染后,就需要判断它的权限。在 hasAuth 方法中,判断当前登陆用户对 item 是否有权限。通过 item 结构获取菜单的 keyisPublic,通过 memoryUtils 获取当用户的 menususername,权限菜单列表和用户名称。对此,我们有四个判断条件,如果当前用户是 admin;如果当前 item 是公开的;当前用户有此 item 的权限: key有没有 menus 中;如果当前用户有此 item 的某个子 item 的权限。所以,根据 username === 'admin' || isPublic || menus.indexOf(key)!== -1 判断。如果当前用户有此 item 的某个子 item 的权限,就进行下一步的查找渲染。这个方法在 getMenuNodes 中进行使用,如果当前用户有 item 对应的权限, 才需要显示对应的菜单项,代码如下所示:
hasAuth = (item) => {
    const { key, isPublic } = item 
    
    const menus = memoryUtils.user.role.menus
    const username = memoryUtils.user.username
    if (username === 'admin' || isPublic || menus.indexOf(key)!== -1) {
      return true
    } else if (item.children) { 
      return !!item.children.find(child => menus.indexOf(child.key)!== -1)
    }
    return false
  }
二、React 结合 Antd 实现权限列表的实现
  1. React 结合 Antd 实现权限列表的实现,完整代码如下所示:
import React, { Component } from 'react'
import { Link, withRouter } from 'react-router-dom'
import { Menu, Icon } from 'antd'
import logo from '../../assets/images/logo.png'
import menuList from '../../config/menuConfig'
import memoryUtils from '../../utils/memoryUtils'
import './index.less'

const { SubMenu } = Menu
class LeftNav extends Component {

  hasAuth = (item) => {
    const { key, isPublic } = item 
    
    const menus = memoryUtils.user.role.menus
    const username = memoryUtils.user.username
    if (username === 'admin' || isPublic || menus.indexOf(key)!== -1) {
      return true
    } else if (item.children) { 
      return !!item.children.find(child => menus.indexOf(child.key)!== -1)
    }
    return false
  }

  getMenuNodes = (menuList) => {
    const path = this.props.location.pathname
    return menuList.reduce((pre, item) => {

      if (this.hasAuth(item)) {
        if (!item.children) {
          pre.push((
            <Menu.Item key={item.key}>
              <Link to={item.key}>
                <Icon type={item.icon}></Icon>
                <span>{item.title}</span>
              </Link>
            </Menu.Item>
          ))
        } else {
          const cItem = item.children.find(cItem => path.indexOf(cItem.key)===0)
          if (cItem) {
            this.openKey = item.key
          }
  
          pre.push((
            <SubMenu key={item.key} title={
              <span>
                <Icon type={item.icon}></Icon>
                <span>{item.title}</span>
              </span>
            }>
              { this.getMenuNodes(item.children) }
            </SubMenu>
          ))
        }
      }
  
      return pre
    }, [])
  }

  componentWillMount () {
    this.menuNodes = this.getMenuNodes(menuList)
  }

  render () {
    let path = this.props.location.pathname
    if (path.indexOf('/product')===0) {
      path = '/product'
    }
    const openKey = this.openKey
  
    return (
      <div className="left-nav">
        <Link to="/" className="left-nav-header">
          <img src={logo} alt="logo"></img>
          <h1>React 后台</h1>
        </Link>

        <Menu
          mode="inline"
          theme="dark"
          selectedKeys={[path]}
          defaultOpenKeys={[openKey]}
        >
          { this.menuNodes }
        </Menu>
      </div>
    )
  }
}

export default withRouter(LeftNav)



https://www.xamrdz.com/web/2x71922092.html

相关文章: