自定义layout - davy-gan/web GitHub Wiki

import React from 'react';
import Link from 'link';
import { Menu, Avatar, Breadcrumb } from 'antd';
import Backend from 'react-dnd-html5-backend';
import { DndProvider } from 'react-dnd';

import routes from '../../config/routes';

const setting = {
  logo: '',
  title: '数据平台',
  headerHeight: 48,
};

const styles = {
  header: {
    display: 'flex',
    alignItems: 'center',
    background: '#1F293D',
    height: setting.headerHeight,
    padding: '0 14px',
    color: 'rgba(255, 255, 255, 0.85)',
    fontSize: 14,
  },
  left: {
    display: 'flex',
    width: 'calc(100vw - 60px)',
  },
  right: {
    flex: 'none',
    width: 60,
  },
  logo: {
    display: 'flex',
    alignItems: 'center',
    flex: 'none',
    color: 'rgba(255, 255, 255, 0.85)',
    marginRight: 32,
  },
  logoImg: {
    height: setting.headerHeight / 2,
  },
  divider: {
    display: 'inline-block',
    margin: '0 8px',
    height: 18,
    width: 1,
    background: '#fff',
  },
  avatar: {
    marginRight: 8,
  },

  breadcrumb: {
    padding: '14px 14px',
  },
  pageContent: {
    background: '#F0F2F5',
  },
  content: {
    display: 'flex',
    minHeight: `calc(100vh - ${setting.headerHeight}px - 50px - 40px`,
  },
  footer: {
    height: 40,
    lineHeight: '40px',
    textAlign: 'center',
    color: '#9B9B9B',
    background: '#F0F2F5',
  },

  menuItem: {
    display: 'inline-block',
    height: setting.headerHeight,
    fontSize: 14,
  },
};

function generateMenu(menuRoutes, parentPath = '', parents = []) {
  const menu = [];
  const matchRoute = {
    key: '',
    routes: [],
  };
  for (const route of menuRoutes) {
    const name = route.name || route.path;
    const path = `${parentPath}/${route.path}`;
    const title = (
      <Link to={path} style={styles.menuItem}>
        {name}
      </Link>
    );
    if (route.routes && route.routes.length && !route.hideInMenu) {
      // 有子元素
      const result = generateMenu(route.routes, path, [
        ...parents,
        {
          ...route,
          path,
        },
      ]);
      if (result.matchRoute.key) {
        matchRoute.key = result.matchRoute.key;
        matchRoute.routes = result.matchRoute.routes;
      }
      menu.push(
        <Menu.SubMenu title={title} key={path}>
          {result.menu}
        </Menu.SubMenu>,
      );
    } else if (route.path && route.component && !route.hideInMenu) {
      menu.push(<Menu.Item key={path}>{title}</Menu.Item>);
    }
    if (window.location.pathname === path) {
      matchRoute.key = path;
      matchRoute.routes = [...parents, route];
    }
  }
  return { menu, matchRoute };
}

const Right = () => (
  <div style={styles.right}>
    <Avatar
      size="small"
      style={styles.avatar}
      src={``}
      alt="avatar"
    />
    <span>xxxx</span>
  </div>
);

const Header = ({ menu, matchRoute }) => (
  <div style={styles.header}>
    <div style={styles.left}>
      <Link style={styles.logo} to="/">
        <img src={setting.logo} alt="logo" style={styles.logoImg} />
        <span style={styles.divider} />
        <span>{setting.title}</span>
      </Link>
      <div>
        <Menu mode="horizontal" theme="dark" selectedKeys={[matchRoute.key]}>
          {menu}
        </Menu>
      </div>
    </div>
    <Right />
  </div>
);

const BasicLayout = props => {
  const { children } = props;
  let layoutRoutes = [];
  for (const route of routes) {
    if (route.component === '../layout/BasicLayout') {
      layoutRoutes = route.routes || [];
      break;
    }
  }
  const { menu, matchRoute } = generateMenu(layoutRoutes);
  return (
    <div>
      <Header menu={menu} matchRoute={matchRoute} />
      <div style={styles.pageContent}>
        <div style={styles.breadcrumb}>
          <Breadcrumb>
            {matchRoute.routes.map(t => (
              <Breadcrumb.Item key={t.path}>
                <Link to={t.path} style={{ fontSize: 12 }}>
                  {t.name}
                </Link>
              </Breadcrumb.Item>
            ))}
          </Breadcrumb>
        </div>
        <div style={styles.content}>
          <DndProvider backend={Backend}>{children}</DndProvider>
        </div>
      </div>
      <div style={styles.footer}>
        xxxxxx
      </div>
    </div>
  );
};

export default BasicLayout;
⚠️ **GitHub.com Fallback** ⚠️