---
title: Tabs 标签页 (done)
order: 19
group:
  path: /components
nav:
  title: 组件
  path: /components
---

## TODO

设计师 确认 `type` 为 `editable-card` 的 icon 样式

## 使用

为页面和功能提供导航的菜单列表。根据实际情况可以和文字、图标、徽标组合使用。

### 基本使用

```jsx
import React from 'react';
import { Tabs } from 'baas-ui';

const { TabPane } = Tabs;

const handleChange = key => {
  console.log(key);
};

export default () => (
  <div>
    <Tabs defaultActiveKey="1" onChange={handleChange}>
      <TabPane tab="菜单名称1" key="1">
        内容1
      </TabPane>
      <TabPane tab="菜单名称2" key="2">
        内容2
      </TabPane>
      <TabPane tab="菜单名称3" key="3">
        内容3
      </TabPane>
    </Tabs>
  </div>
);
```

### 带图标

```jsx
import React from 'react';
import { Tabs, Icons } from 'baas-ui';

const { TabPane } = Tabs;
const { InfoCircleIcon } = Icons;

const handleChange = key => {
  console.log(key);
};

export default () => (
  <div>
    <Tabs defaultActiveKey="1" onChange={handleChange}>
      <TabPane
        tab={
          <span style={{ verticalAlign: 'middle' }}>
            <InfoCircleIcon
              fill="currentColor"
              wrapperStyle={{ verticalAlign: 'middle' }}
            />
            <span style={{ verticalAlign: 'middle' }}>菜单名称1</span>
          </span>
        }
        key="1"
      >
        内容1
      </TabPane>
      <TabPane
        tab={
          <span style={{ verticalAlign: 'middle' }}>
            <InfoCircleIcon
              fill="currentColor"
              wrapperStyle={{ verticalAlign: 'middle' }}
            />
            <span style={{ verticalAlign: 'middle' }}>菜单名称2</span>
          </span>
        }
        key="2"
      >
        内容2
      </TabPane>
      <TabPane
        tab={
          <span style={{ verticalAlign: 'middle' }}>
            <InfoCircleIcon
              fill="currentColor"
              wrapperStyle={{ verticalAlign: 'middle' }}
            />
            <span style={{ verticalAlign: 'middle' }}>菜单名称3</span>
          </span>
        }
        key="3"
      >
        内容3
      </TabPane>
    </Tabs>
  </div>
);
```

### 带徽标

```jsx
import React from 'react';
import { Tabs, Badge } from 'baas-ui';

const { TabPane } = Tabs;

const handleChange = key => {
  console.log(key);
};

export default () => (
  <div>
    <Tabs defaultActiveKey="1" onChange={handleChange}>
      <TabPane
        tab={
          <span>
            菜单名称2
            <Badge count="2" style={{ marginTop: -3 }} />
          </span>
        }
        key="1"
      >
        内容1
      </TabPane>
      <TabPane
        tab={
          <span>
            菜单名称2
            <Badge count="2" style={{ marginTop: -3 }} />
          </span>
        }
        key="2"
      >
        内容2
      </TabPane>
      <TabPane
        tab={
          <span>
            菜单名称3
            <Badge count="3" style={{ marginTop: -3 }} />
          </span>
        }
        key="3"
      >
        内容3
      </TabPane>
    </Tabs>
  </div>
);
```

### 禁用

```jsx
import React from 'react';
import { Tabs } from 'baas-ui';

const { TabPane } = Tabs;

const handleChange = key => {
  console.log(key);
};

export default () => (
  <div>
    <Tabs defaultActiveKey="1" onChange={handleChange}>
      <TabPane tab="菜单名称1" key="1">
        内容1
      </TabPane>
      <TabPane tab="菜单名称2" key="2" disabled>
        内容2
      </TabPane>
      <TabPane tab="菜单名称3" key="3">
        内容3
      </TabPane>
    </Tabs>
  </div>
);
```

### 摆放位置

```jsx
import React from 'react';
import { Tabs, Radio } from 'baas-ui';

const { TabPane } = Tabs;

class TabPositon extends React.Component {
  constructor() {
    super();
    this.state = {
      mode: 'top',
    };
  }

  handleModeChange = e => {
    this.setState({ mode: e.target.value });
  };

  render() {
    const { mode } = this.state;
    return (
      <div>
        <Radio.Group
          onChange={this.handleModeChange}
          value={mode}
          style={{ marginBottom: 32 }}
        >
          <Radio.Button value="top">Top</Radio.Button>
          <Radio.Button value="right">Right</Radio.Button>
          <Radio.Button value="bottom">Bottom</Radio.Button>
          <Radio.Button value="left">Left</Radio.Button>
        </Radio.Group>
        <Tabs defaultActiveKey="1" tabPosition={mode}>
          <TabPane tab="菜单名称1" key="1">
            内容1
          </TabPane>
          <TabPane tab="菜单名称2" key="2">
            内容2
          </TabPane>
          <TabPane tab="菜单名称3" key="3">
            内容3
          </TabPane>
        </Tabs>
      </div>
    );
  }
}

export default TabPositon;
```

### 可以滚动

```jsx
import React from 'react';
import { Tabs, Radio } from 'baas-ui';

const { TabPane } = Tabs;

class TabPositon extends React.Component {
  constructor() {
    super();
    this.state = {
      mode: 'top',
    };
  }

  handleModeChange = e => {
    this.setState({ mode: e.target.value });
  };

  render() {
    const { mode } = this.state;
    return (
      <div>
        <Radio.Group
          onChange={this.handleModeChange}
          value={mode}
          style={{ marginBottom: 32 }}
        >
          <Radio.Button value="top">Top</Radio.Button>
          <Radio.Button value="right">Right</Radio.Button>
          <Radio.Button value="bottom">Bottom</Radio.Button>
          <Radio.Button value="left">Left</Radio.Button>
        </Radio.Group>
        <Tabs
          defaultActiveKey="1"
          tabPosition={mode}
          style={{ height: mode === 'left' || mode === 'right' ? 300 : 'auto' }}
        >
          {[...Array(30).keys()].map(i => (
            <TabPane tab={`Tab-${i}`} key={i}>
              Content of tab {i}
            </TabPane>
          ))}
        </Tabs>
      </div>
    );
  }
}

export default TabPositon;
```

### 卡片式页签

通过设置 `type` 来显示页签的基本样式，可选值有 `line`(默认)、`card`、`editable-card`

```jsx
import React from 'react';
import { Tabs } from 'baas-ui';

const { TabPane } = Tabs;

const handleChange = key => {
  console.log(key);
};

export default () => (
  <div>
    <Tabs defaultActiveKey="1" onChange={handleChange} type="card">
      <TabPane tab="菜单名称1" key="1">
        内容1
      </TabPane>
      <TabPane tab="菜单名称2" key="2">
        内容2
      </TabPane>
      <TabPane tab="菜单名称3" key="3">
        内容3
      </TabPane>
    </Tabs>
  </div>
);
```

### 可编辑 Tab

```jsx
import React from 'react';
import { Tabs } from 'baas-ui';

const { TabPane } = Tabs;

class TabEditable extends React.Component {
  constructor() {
    super();
    const tabPanes = [
      { tab: '菜单名称1', content: '内容1', key: '1' },
      { tab: '菜单名称2', content: '内容2', key: '2' },
    ];
    this.newTabIndex = 0;
    this.state = {
      activeKey: tabPanes[0].key,
      tabPanes,
    };
  }

  handleTabChange = key => {
    this.setState({ activeKey: key });
  };

  handleEdit = (key, action) => {
    console.log('edit:', key, action);
    this[action](key);
  };

  add = () => {
    const { tabPanes } = this.state;
    const activeKey = `newTab${this.newTabIndex++}`;
    tabPanes.push({
      tab: `新建页签${this.newTabIndex}`,
      content: '新内容',
      key: activeKey,
    });
    this.setState({ tabPanes, activeKey });
  };

  remove = targetKey => {
    let { activeKey, tabPanes } = this.state;
    let lastIndex;
    tabPanes.forEach((pane, i) => {
      if (pane.key === targetKey) {
        lastIndex = i - 1;
      }
    });
    const nextTabPanes = tabPanes.filter(pane => pane.key !== targetKey);
    if (nextTabPanes.length && activeKey === targetKey) {
      if (lastIndex >= 0) {
        activeKey = nextTabPanes[lastIndex].key;
      } else {
        activeKey = nextTabPanes[0].key;
      }
    }
    this.setState({ tabPanes: nextTabPanes, activeKey });
  };

  render() {
    const { tabPanes, activeKey } = this.state;
    return (
      <div>
        <Tabs
          activeKey={activeKey}
          onChange={this.handleTabChange}
          onEdit={this.handleEdit}
          type="editable-card"
        >
          {tabPanes.map(pane => (
            <TabPane tab={pane.tab} key={pane.key}>
              {pane.content}
            </TabPane>
          ))}
        </Tabs>
      </div>
    );
  }
}

export default TabEditable;
```
