umi引入antd的全局layout

文章前景

常见的后台管理系统中,通常是页面属性的局部刷新,下面我们仿照若依(侧边布局),实现相关功能。
若依在线演示antd-3x文档
在这里插入图片描述

组件调整

官方代码是以类组件来实现,本次我们修改为函数组件模式。

//官方示例
 class SiderDemo extends React.Component {
	 state = {
	    collapsed: false,
	  };

	  toggle = () => {
	    this.setState({
	      collapsed: !this.state.collapsed,
	    });
	  };
}
//import {useState} from "react";
const SysMenu = (props)=>{
  const [collapsed,setCollapsed] = useState(false);
  const onCollapse = () => {
    setCollapsed(!collapsed);
  };
}

函数组件中由于生命周期的问题,无法直接对state进行修改,本次使用hook(useState)完成。

路由配置

按照umi的官方介绍介绍,我们修改src下的全局路由,将前文提到的组件改为layouts的子组件,配置如下。

module.exports = [
  {
    path:"/",
    component:"../layouts/index.js",
    routes:[
      {
        exact: true,
        path: '/practice/calculate',
        component: '../pages/calculate/calculate.js'
      },
      ...routeConsole(practice_routes)
    ]
  },
];

组件传递

下面回到/src/layouts/index.js中,我们把子组件作为孩子节点传递给SysMenu(导航),相关代码如下:

// 引入布局和子组件
import SysMenu  from '../layouts/menu/SysMenu.js';
 // 分配路由
const BasicRoute = (props) => {
  return (
    <SysMenu>
      {props.children}
    </SysMenu>
  );
}
export default BasicRoute;

下面我们回到SysMenu中,BasicRoute组件中,我们把配置的子路由信息作为SysMenu的属性传递给了SysMenu,因此可以通过{props.children}方法拿到相关子组件信息。

const SysMenu = (props)=>{

  const [collapsed,setCollapsed] = useState(false);
  const onCollapse = () => {
    setCollapsed(!collapsed);
  };

  return (
    <Layout>
      <Sider trigger={null} collapsible collapsed={collapsed}>
        <div className={layoutModule.logo} >
        </div>
        <Menu theme="dark" mode="inline" defaultSelectedKeys={['practice']}>
        //稍后配置
        </Menu>
      </Sider>
      <Layout>
        <Header style={{ background: '#fff', padding: 0 }}>
        </Header>
        <Content className={layoutModule.content}>
          <div style={{ padding: 24, background: '#fff', minHeight: '90%' }}>
            {props.children}
          </div>
        </Content>
        <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
      </Layout>
    </Layout>
  );
}
export default SysMenu;

将子组件信息放置在Content标签下,这样就能实现页面的整体布局不变,而是局部内容刷新了。

菜单配置

因为umi是基于路由的单页面应用,路由的变化会导致页面的变化,在菜单配置中我们需要添Link属性,实现路径的跳转而发生页面的刷新。相关<Menu>配置如下

        <Menu theme="dark" mode="inline" defaultSelectedKeys={['practice']}>
          <SubMenu
            key="practice"
            title={
              <span>
                  <Icon type="build" />
                  <span>练习模块</span>
                  <Link to="/practice/calculate"/>
                </span>
            }
          >
            <Link to="/practice"/>
            <Menu.Item key="calculator">
              <Icon type="calculator"/>
              <span >计算程序</span>
              <Link to="/practice/calculate"/>
            </Menu.Item>
            <Menu.Item key="air" >
              <Icon type="skin"/>
              <span>中央空调</span>
              <Link to="/practice/air"/>
            </Menu.Item>
          </SubMenu>
          <SubMenu
            key="practice"
            title={
              <span>
                  <Icon type="build" />
                  <span>信息管理</span>
                  <Link to="/practice/calculate"/>
                </span>
            }
          >
            <Menu.Item key="user" >
              <Icon type="user"/>
              <span>用户管理</span>
              <Link to="/practice/user"/>
            </Menu.Item>  
          </SubMenu>
          {/*<Menu.Item key="1">*/}
          {/*  <Icon type="appstore" />*/}
          {/*  <span>practice</span>*/}
          {/*</Menu.Item>*/}
        </Menu>

其中defaultSelectedKeys表示默认打开的菜单。

动态路由

前面我们配置了路由地址,实际情况会根据用户的不同权限展示不同的菜单,下面我们将菜单抽取出一个专门的组件来动态处理。文件目录如下所示:
在这里插入图片描述
其中SysMenu文件中菜单配置变化如下:
在这里插入图片描述
目前我们指定菜单属性只有5个属性(后台已封装为父子结构),分别为nameurliconkeychildren,按照顺序依次表现为菜单名称,菜单路由,菜单图标,唯一key,菜单的子级节点。数据结构如下所示:

  const menuList = [
    {
      name:'练习程序',
      url:'#',
      icon:'build',
      key:'practice',
      children:[
        {
          name:'计算程序',
          url:'/practice/calculate',
          icon:'calculator',
          key:'calculate',
          children:[],
        },{
          name:'中央空调',
          url:'/practice/air',
          icon:'skin',
          key:'air',
          children:[],
        },
      ]
    },{
      name:'信息管理',
      url:'#',
      icon:'build',
      key:'infoManage',
      children:[
        {
          name:'计算程序',
          url:'/infoManage/user',
          icon:'user',
          key:'user',
          children:[],
        },
      ]
    },
  ];

MenuTree组件整体结构如下,其中extractMenus方法则是将后台返回的权限菜单进行转化为对应的配置。

const MenuTree = ()=>{  
  return(
    <Menu theme="dark" mode="inline" defaultSelectedKeys={[menuList[0].key]}>
      {extractMenus(menuList)}
    </Menu>
  );
}
export default MenuTree;
  const extractMenus = (list) =>{
    return list.map((item, index) => (
      doExtractMenus(item)
    ));
  }

  //显示菜单项
  const doExtractMenus = (item)=>{
    if(item.children.length == 0)
    {
      return (
        <Menu.Item key={item.key}>
          <Icon type={item.icon}/>
          <span>{item.name}</span>
          <Link to={item.url}/>
        </Menu.Item>
      );
    }
    else
    {
      return (
        <SubMenu key={item.key} title={
          <span>
            <Icon type={item.icon}/>
            <span>{item.name}</span>
          </span>
        }>
          {extractMenus(item.children)}
        </SubMenu>
      );
    }
  }

常见问题

  • 布局很小
    页面上的布局没有填充整个页面,可以通过下面的配置来解决问题。
/*
umi:全局约定样式
路径:umi-react/src/global.css,其中umi-react是根目录 
*/
/*ID选择器*/
#root {
  height: 100%;
}
/*!important用来覆盖antdui原有的css属性值*/
.ant-layout {
  display: flex;
  flex: auto;
  flex-direction: column;
  min-height: 100%;
  background: #f0f2f5;
}

源码地址

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值