主界面布局

产品主界面通常包含顶部导航、页脚、侧边栏导航、主要内容区域等。

产品主界面布局

JUI使用一切皆为组件的架构原则,将产品主界面当作一个大的功能组件,并将与之相关的所有资源存放在layout/main目录中。

主界面目录结构

layout/main
├── components
│   ├── footer #页脚
│   │   ├── global-footer
│   │   │   ├── index.js
│   │   │   └── index.less
│   │   └── index.js
│   ├── header #顶部导航
│   │   ├── global-header
│   │   │   ├── index.js
│   │   │   ├── index.less
│   │   │   └── right-content.js
│   │   ├── index.js
│   │   ├── index.less
│   │   └── top-nav-header
│   │       ├── index.js
│   │       └── index.less
│   ├── page-wrapper #栅格布局
│   │   ├── index.js
│   │   └── index.less
│   └── sider-menu #侧边栏
│       ├── base-menu.js
│       ├── index.js
│       ├── index.less
│       ├── sider-menu-utils.js
│       └── sider-menu.js
├── config.js #主界面布局配置文件
├── index.js #主界面布局入口脚本
├── index.less #主界面布局样式
├── menu.js #导航菜单数据
├── pages #内容区域内的组件(页面)
│   ├── basic-form
│   │   ├── index.js
│   ├── basic-table
│   │   └── index.js
│   ├── dashboard
│   │   └── index.js
│   ├── search-table
│   │   └── index.js
│   └── step-form
│       └── index.js
└── routes.js #主界面路由配置

最佳响应式布局

JUI支持配置上下、左右两种基本布局,自适配PC端、移动端、Pad端、及不同大小屏幕。

上下布局

上下布局

左右布局

左右布局

响应式移动端

移动端

响应式Pad端

Pad端

默认支持深、浅两种主题

左右结构的浅色主题

浅色主题

上下结构的浅色主题

浅色主题上下结构

主界面布局配置

JUI的产品主界面支持上下、左右两种结构,主题支持深、浅两种模式,内容区域支持定宽、自适应宽度,支持固定顶部导航、侧边栏导航等配置。

// views/index/layout/main/config.js
export default {
  navTheme: 'light', // 菜单的主题 content: dark or light
  layout: 'topmenu', // 菜单的布局,值为 sidemenu 菜单显示在左侧,值为 topmenu 菜单显示在顶部
  contentWidth: 'Fluid', // 内容的布局 Fixed 为定宽到1200px ,Fluid 为流式布局
  fixedHeader: false, // 固定页头
  autoHideHeader: false, // 下滑时自动隐藏页头
  fixSiderbar: false, // 固定菜单
  sysName: 'JUI' //系统名称
}

新增主界面页面

这里的页面指配置了主界面的路由,与顶部导航、侧边栏导航菜单结合,能够通过链接直接访问的组件。

1、在layout/main/pages下新建js文件

layout/main
├── index.js
├── pages #页面存放目录
│   └── new-page.js #新建页面
└── routes.js #路由配置

页面内容遵循React组件规则:

// layout/main/pages/new-page.js
import React, { Component, Fragment } from 'react'

export default class newPage extends Component {
  render() {
    return (
      <Fragment>
        新增页面内容
      </Fragment>
    )
  }
}

2、将页面加入路由

// layout/main/routes.js

import Loadable from '@/components/loadable' //懒加载组件

const Dashboard = Loadable(() => import('./pages/dashboard')) //首页面板
const newPage = Loadable(() => import('./pages/new-page')) //新增页面

export default [
  { path: '/dashboard', component: Dashboard },
  { path: '/new-page', component: newPage }
]

3、将页面导航加入菜单

// layout/main/menu.js

const menuData = [
  {
    name: '首页',
    icon: 'dashboard',
    path: 'dashboard'
  },
  {
    name: '新建页面',
    path: 'new-page'
  }
]

访问http://localhost:8080/index.html#/new-page就能看到页面内容了。

新增页面

自定义区域内容

JUI使用了业内中后台产品界面布局的最佳实践,完成了大部分的布局逻辑,大多数业务场景只有修改产品主界面布局的右上角顶部导航区域、或者内容的页脚区域。

顶部导航

业务场景可能需要修改或扩展主界面右上角的内容,JUI已将右上角内容独立成组件,可在layout/main/components/header/gloabl-header/right-content.js文件中扩展或修改内容。

import React, { PureComponent } from 'react'
import { Spin, Dropdown, Menu, Icon, Avatar } from 'antd'
import styles from './index.less'

export default class GlobalHeaderRight extends PureComponent {
  render() {
    const {
      currentUser,
      onMenuClick,
      theme,
    } = this.props

    const menu = (
      <Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
        <Menu.Item key="logout">
          <Icon type="logout" />退出登录
        </Menu.Item>
      </Menu>
    )

    let className = styles.right

    if (theme === 'dark') {
      className = `${styles.right}  ${styles.dark}`
    }

    return (
      <div className={className}>
        {currentUser.name ? (
          <Dropdown overlay={menu}>
            <span className={`${styles.action} ${styles.account}`}>
              <Avatar size="small" className={styles.avatar} src={currentUser.avatar} />
              <span className={styles.name}>{currentUser.name}</span>
            </span>
          </Dropdown>
        ) : (
            <Spin size="small" style={{ marginLeft: 8 }} />
          )}
      </div>
    )
  }
}

页脚

可在layout/main/components/footer/index.js文件中扩展或修改页脚内容。

import React, { Fragment } from 'react';
import { Layout, Icon } from 'antd';
import GlobalFooter from './global-footer';

const { Footer } = Layout;
const FooterView = () => (
  <Footer style={{ padding: 0 }}>
    <GlobalFooter
      links={[
        // {
        //   key: '塞伯坦CYB-CLI',
        //   title: '塞伯坦CYB-CLI',
        //   href: 'https://github.com/jd-cyb/cyb-cli',
        //   blankTarget: true,
        // },
        // {
        //   key: 'github',
        //   title: <Icon type="github" />,
        //   href: 'https://github.com/jd-cyb',
        //   blankTarget: true,
        // }
      ]}
      copyright={
        <Fragment>
          Copyright <Icon type="copyright" /> 2019 塞伯坦前端架构组
        </Fragment>
      }
    />
  </Footer>
);
export default FooterView;

响应式布局组件

JUI已在产品主界面的内容区域集成栅格布局,栅格布局是网页中最常用的布局,其特点就是按照一定比例划分页面,能够随着屏幕的变化依旧保持比例,从而具有弹性布局的特点。结合AntDesign的栅格组件提供的功能更为强大,能够设置间距、具有支持响应式的比例设置,以及支持 flex 模式,基本上涵盖了大部分的布局场景。

// layout/main/components/page-wrapper/index.js

import React, { PureComponent } from 'react';
import styles from './index.less';

export default class GridContent extends PureComponent {
  render() {
    const { contentWidth, children } = this.props;
    let className = `${styles.main}`;
    if (contentWidth === 'Fixed') {
      className = `${styles.main} ${styles.wide}`;
    }
    return <div className={className}>{children}</div>;
  }
}