Layout 页面布局

提供页面框架性的 Layout 以及基础区块布局,除了 Layout.Main 必须以外, 其它的组件在页面中可以按需自由搭配使用。

Layout

import Layout from '@icedesign/layout';

页面布局,一个页面有且只能有一个 Layout 组件。

参数(props)

参数名 说明 类型 默认值
fixable 开启布局模块滚动跟随模式 boolean false

fixable 一旦设置为 true 则整个页面所有模块都固定高度,内容区域不可滚动。子组件通过 scrollable props 使其可滚动,以此实现主体内容滚动,其余模块 fixed 的效果。

Layout.Section

辅助布局组件,会创建 100% 宽度的一整行。当某一块区域需要两个模块左右排列,则需要使用 Layout.Section 组件包裹。

如:

<Layout.Section>
  <Layout.Aside />
  <Layout.Main />
</Layout.Section>

参数(props)

参数名 说明 类型 默认值
scrollable 区域可滚动 (<Layout fixable={true} /> 下可用) boolean false

Layout.Header

顶部布局,默认 flex 布局,并且内部元素垂直居中对齐,可通过 style 属性修改。

参数(props)

参数名 说明 类型 默认值
type 配置皮肤色 string normal

Layout.Aside

侧边栏,根据嵌套顺序,可左右布局。

参数(props)

参数名 说明 类型 默认值
type 配置Aside 皮肤色 string -

Layout.Main

参数(props)

参数名 说明 类型 默认值
scrollable 区域可滚动 (<Layout fixable={true} /> 下可用) boolean false

主体内容。

Layout.Footer

页脚布局。

参数(props)

参数名 说明 类型 默认值
type 配置Aside 皮肤色 string -

DEMO 列表

基本结构

基础组件 Header Main Footer,默认宽度都是 100%。当需要侧边栏 Aside 组件,需要使用辅助布局组件 Section 包裹起来。

通过各组件的先后顺序实现多样性布局。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';

class App extends Component {
  render() {
    return (
      <div>
        <Layout>
          <Layout.Header style={{
            height: 80,
          }} type="secondary">header</Layout.Header>
          <Layout.Main style={{height: 200, background: '#fff'}}>Main</Layout.Main>
          <Layout.Footer style={{
            height: 80,
          }} type="secondary">Footer</Layout.Footer>
        </Layout>

        <div style={{height: 20}}></div>

        <Layout>
          <Layout.Header style={{
            height: 80,
          }} type="secondary">header</Layout.Header>
          <Layout.Section>
            <Layout.Aside style={{
              width: 80,
            }} type="secondary">Aside</Layout.Aside>
            <Layout.Main style={{height: 200, background: '#fff'}}>Main</Layout.Main>
          </Layout.Section>
          <Layout.Footer style={{
            height: 80,
          }} type="secondary">Footer</Layout.Footer>
        </Layout>

        <div style={{height: 20}}></div>

        <Layout>
          <Layout.Header style={{
            height: 80,
          }} type="secondary">header</Layout.Header>
          <Layout.Section style={{ padding: '20px 40px' }}>
            <Layout.Aside style={{
              width: 80,
            }} type="secondary" >Aside</Layout.Aside>
            <Layout.Main style={{height: 200, background: '#fff'}}>Main</Layout.Main>
          </Layout.Section>
          <Layout.Footer style={{
            height: 80,
          }} type="secondary">Footer</Layout.Footer>
        </Layout>

        <div style={{height: 20}}></div>

        <Layout>
          <Layout.Header style={{
            height: 80,
          }} type="secondary">header</Layout.Header>
          <Layout.Section>
            <Layout.Aside style={{
              width: 80,
            }} type="secondary">Aside</Layout.Aside>
            <Layout.Main style={{height: 500, background: '#fff'}}>Main</Layout.Main>
            <Layout.Aside style={{
              width: 80,
            }} type="secondary">Aside</Layout.Aside>
          </Layout.Section>
          <Layout.Footer style={{
            height: 80,
          }} type="secondary">Footer</Layout.Footer>
        </Layout>

        <div style={{height: 20}}></div>

        <Layout>
          <Layout.Aside style={{
            width: 80,
          }} type="secondary">Aside</Layout.Aside>
          <Layout.Section>
            <Layout.Header style={{
              height: 80,
            }} type="secondary">header</Layout.Header>
            <Layout.Main style={{
              height: 200, background: '#fff'
            }}>Main</Layout.Main>
            <Layout.Footer style={{
              height: 80,
            }} type="secondary">Footer</Layout.Footer>
          </Layout.Section>
        </Layout>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);
.ice-layout {
  color: #fff;
  text-align: center;
  margin-bottom: 50px;
  background-color: #eee;
}
.ice-layout-header {
  line-height: 50px;
  background-color: rgba(27, 115, 225, 0.5) !important;;
}
.ice-layout-aside {
  line-height: 120px;
  background-color: rgba(27, 115, 225, 0.7) !important;;
}
.ice-layout-main {
  line-height: 120px;
  background-color: rgba(27, 115, 225, 1);
}
.ice-layout-footer {
  line-height: 50px;
  background-color: rgba(27, 115, 225, 0.5);
}

通过 type 定制主题

通过 type 属性可以定制组件的样式,Header/Footer/Aside 支持 type 属性,并且与 Nav 组件保持一致

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';
import { Icon, Dropdown, Nav, Radio } from '@alifd/next';

class App extends Component {
  state = {
    type: 'normal'
  };

  render() {
    return (
      <Layout style={{ minHeight: '100vh' }}>
        <Layout.Aside
          type={this.state.type}
        >
          <Logo />
          <Nav type={this.state.type}>
            <Nav.Group label="需求">
              <Nav.Item icon="account">需求1</Nav.Item>
              <Nav.Item icon="account">需求2</Nav.Item>
              <Nav.Item icon="account">需求3</Nav.Item>
            </Nav.Group>
            <Nav.Group label="我的">
              <Nav.Item icon="account">资料</Nav.Item>
              <Nav.Item icon="account">设置</Nav.Item>
              <Nav.Item icon="account">主题</Nav.Item>
            </Nav.Group>
          </Nav>
        </Layout.Aside>
        <Layout.Section>
          <Layout.Header
            style={{
              height: '60px',
              padding: '0 20px',
              justifyContent: 'space-between',
            }}
            type={this.state.type}
          >
            <Nav
              type={this.state.type}
              direction="hoz"
              triggerType="hover"
            >
              <Nav.Item key="home">Home</Nav.Item>
              <Nav.SubNav label="Component" selectable>
                <Nav.Item key="next">ICE</Nav.Item>
                <Nav.Item key="mext">Next</Nav.Item>
              </Nav.SubNav>
              <Nav.Item key="document">Document</Nav.Item>
            </Nav>
            <div>ICE</div>
          </Layout.Header>
          <Layout.Main
            style={{
              padding: 20,
              margin: '0 24px'
            }}
          >
            <Radio.Group
              shape="button" size="medium"
              value={this.state.type}
              onChange={(value) => {
                this.setState({
                  type: value
                })
              }}
            >
              <Radio value="normal">type="normal"</Radio>
              <Radio value="primary">type="primary"</Radio>
              <Radio value="secondary">type="secondary"</Radio>
              <Radio value="line">type="line"</Radio>
              <Radio value="line">type="none"</Radio>
            </Radio.Group>
          </Layout.Main>
          <Layout.Footer
            type={this.state.type}
            style={{
              textAlign: 'center',
              lineHeight: '36px'
            }}
          >
            <p style={{ color: '#999' }}>
              © 2017-2018 xxxx团队 版权所有 系统维护者:@xx 如有问题随时联系!
              <br /><a href="https://alibaba.github.io/ice" target="_blank"> ICE </a> 提供技术支持
            </p>
          </Layout.Footer>
        </Layout.Section>
      </Layout>
    );
  }
}

// 项目内敛 Logo 组件
class Logo extends Component {
  render() {
    return (
      <div
        className="logo"
        style={{
          overflow: 'hidden',
          height: 60,
          color: '#f40',
          textAlign: 'center',
          ...this.props.style
        }}
      >
        <div
          style={{
            height: 60,
            lineHeight: '60px',
            fontSize: 20,
            ...this.props.style
          }}
        >
          Your Logo
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

Aside 收起展开模式

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';
import { Icon, Nav } from '@alifd/next';

class App extends Component {
  state = {
    collapse: false,
  };

  render() {
    const { collapse } = this.state;
    return (
      <Layout style={{ minHeight: '100vh' }}>
        <Layout.Aside
          type="primary"
          style={{
            width: collapse ? 60 : 200
          }}
        >
          <Logo text={collapse ? 'go' : 'your-logo'} />
          <div style={{
            display: 'flex',
            justifyContent: 'center',
            margin: '20px 0'
          }}>
            <Icon
              type={collapse ? 'arrow-right' : 'arrow-left'}
              onClick={() => {
                this.setState({
                  collapse: !this.state.collapse
                })
              }}
            />
          </div>
          <Nav type="primary" iconOnly={this.state.collapse} hasTooltip={true}>

            <Nav.SubNav icon="account" label="需求">
              <Nav.Item icon="account">需求1</Nav.Item>
              <Nav.Item icon="account">需求2</Nav.Item>
              <Nav.Item icon="account">需求3</Nav.Item>
            </Nav.SubNav>
            <Nav.SubNav icon="account" label="我的">
              <Nav.Item icon="account">资料</Nav.Item>
              <Nav.Item icon="account">设置</Nav.Item>
              <Nav.Item icon="account">主题</Nav.Item>
            </Nav.SubNav>
          </Nav>
        </Layout.Aside>
        <Layout.Section>
          <Layout.Header
            style={{
              height: '60px',
              padding: '0 20px',
              justifyContent: 'space-between',
            }}
            type="primary"
          >
            <Nav
              type="primary"
              direction="hoz"
              triggerType="hover"
            >
              <Nav.Item key="home">Home</Nav.Item>
              <Nav.SubNav label="Component" selectable>
                <Nav.Item key="next">ICE</Nav.Item>
                <Nav.Item key="mext">Next</Nav.Item>
              </Nav.SubNav>
              <Nav.Item key="document">Document</Nav.Item>
            </Nav>
          </Layout.Header>
          <Layout.Main
            style={{
              padding: 20,
              height: 500,
              margin: '0 24px'
            }}
          >
            Main
          </Layout.Main>
          <Layout.Footer
            type="primary"
            style={{
              textAlign: 'center',
              lineHeight: '36px'
            }}
          >
            <p style={{ color: '#999' }}>
              © 2017-2018 xxxx团队 版权所有 系统维护者:@xx 如有问题随时联系!
              <br /><a href="https://alibaba.github.io/ice" target="_blank"> ICE </a> 提供技术支持
            </p>
          </Layout.Footer>
        </Layout.Section>
      </Layout>
    );
  }
}

// 项目内敛 Logo 组件
class Logo extends Component {
  render() {
    const { text } = this.props;
    return (
      <div
        className="logo"
        style={{
          overflow: 'hidden',
          height: 60,
          color: '#f40',
          textAlign: 'center',
          ...this.props.style
        }}
      >
        <div
          style={{
            height: 60,
            lineHeight: '60px',
            fontSize: 20,
            ...this.props.style
          }}
        >
          {text}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

Header 吸顶

Header 固定(吸顶),其他区域滚动。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';

class App extends Component {
  render() {
    return (
      <Layout fixable={true}>
        <Layout.Header style={{
          height: 80,
        }} type="primary">Header</Layout.Header>
        <Layout.Section scrollable={true}>
          <Layout.Aside style={{
            width: 200,
          }} type="primary">
            <br />
            Aside
          </Layout.Aside>
          <Layout.Main>
            <p>Main</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动 end</p>
            <Layout.Footer>Footer</Layout.Footer>
          </Layout.Main>
        </Layout.Section>
      </Layout>
    );
  }
}

ReactDOM.render(<App />, mountNode);

Header&Aside 固定,Aside 内容可滚动

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';

class App extends Component {
  render() {
    return (
      <Layout fixable={true}>
        <Layout.Header style={{
          height: 80,
        }} type="primary">&nbsp;&nbsp;&nbsp;&nbsp;Header</Layout.Header>
        <Layout.Section>
          <Layout.Aside style={{
            width: 150,
          }} type="primary" scrollable={true}>
            <p>Aside</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
          </Layout.Aside>
          <Layout.Main scrollable={true}>
            <p>Main</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动 end</p>
            <Layout.Footer style={{
              height: 80,
            }} type="primary">Footer</Layout.Footer>
          </Layout.Main>
        </Layout.Section>
      </Layout>
    );
  }
}

ReactDOM.render(<App />, mountNode);

Aside&Header 固定

Aside Header 固定位置布局,将 Footer 放在 Main 里一同滚动。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';

class App extends Component {
  render() {
    return (
      <Layout fixable={true}>
        <Layout.Aside style={{
          width: 80,
        }} type="primary">
          <br />
          Aside
        </Layout.Aside>
        <Layout.Section>
          <Layout.Header style={{
            height: 80,
          }} type="primary">&nbsp;&nbsp;&nbsp;&nbsp;Header</Layout.Header>
          <Layout.Main scrollable={true}>
            <p>Main</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <Layout.Footer style={{
              height: 80,
            }} type="primary">Footer</Layout.Footer>
          </Layout.Main>
        </Layout.Section>
      </Layout>
    );
  }
}

ReactDOM.render(<App />, mountNode);

Aside 固定

Aside 固定,其他区域滚动

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';

class App extends Component {
  render() {
    return (
      <Layout fixable={true}>
        <Layout.Aside style={{
          width: 200,
        }} type="primary">
          <br />
          Aside
        </Layout.Aside>
        <Layout.Section scrollable={true}>
          <Layout.Header type="primary" style={{
            height: 80
          }}>&nbsp;&nbsp;&nbsp;&nbsp;Header</Layout.Header>
          <Layout.Main>
            <p>Main</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
            <p style={{ height: 200 }}>内容可滚动</p>
          </Layout.Main>
          <Layout.Footer style={{
            height: 200
          }}>Footer</Layout.Footer>
        </Layout.Section>
      </Layout>
    );
  }
}

ReactDOM.render(<App />, mountNode);

上中下应用示例

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Layout from '@icedesign/layout';
import { Nav } from '@alifd/next';

class App extends Component {
  render() {
    return (
      <Layout>
        <Layout.Header style={{ padding: '12px 50px' }} type="primary">
          <Nav
            type="primary"
            direction="hoz"
            triggerType="hover"
          >
            <Nav.Item key="home">Home</Nav.Item>
            <Nav.SubNav label="Component" selectable>
              <Nav.Item key="next">ICE</Nav.Item>
              <Nav.Item key="mext">Next</Nav.Item>
            </Nav.SubNav>
            <Nav.Item key="document">Document</Nav.Item>
          </Nav>
        </Layout.Header>
        <Layout.Section style={{ padding: '0 50px' }}>
          <Layout.Main
            style={{
              background: '#fff',
              padding: 24,
              minHeight: 280
            }}
          >
            Main
          </Layout.Main>
        </Layout.Section>
        <Layout.Footer
          type="secondary"
          style={{
            textAlign: 'center',
            lineHeight: '36px'
          }}
        >
          <p>
            © 2017-2018 xxxx团队 版权所有 系统维护者:@xx 如有问题随时联系!
            <br />{' '}
            <a href="//ice.alibaba-inc.com" target="_blank">ICE</a>
            {' '}
            提供技术支持
          </p>
        </Layout.Footer>
      </Layout>
    );
  }
}

ReactDOM.render(<App />, mountNode);