Tabs标签页

选项卡切换组件。

何时使用

提供平级的区域将大块内容进行收纳和展现,保持界面整洁。

Choerodon UI 依次提供了三级选项卡,分别用于不同的场景。

  • 卡片式的页签,提供可关闭的样式,常用于容器顶部。

  • 标准线条式页签,用于容器内部的主功能切换,这是最常用的 Tabs。

  • RadioButton 可作为更次级的页签来使用。

代码演示

Tabs 标签页 - 图1

基本

默认选中第一项。

  1. import { Tabs } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. function callback(key) {
  4. console.log(key);
  5. }
  6. ReactDOM.render(
  7. <Tabs defaultActiveKey="1" onChange={callback}>
  8. <TabPane tab="Tab 1" key="1">
  9. Content of Tab Pane 1
  10. </TabPane>
  11. <TabPane tab="Tab 2" key="2">
  12. Content of Tab Pane 2
  13. </TabPane>
  14. <TabPane tab="Tab 3" key="3">
  15. Content of Tab Pane 3
  16. </TabPane>
  17. </Tabs>,
  18. mountNode,
  19. );

Tabs 标签页 - 图2

禁用

禁用某一项。

  1. import { Tabs } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. ReactDOM.render(
  4. <Tabs defaultActiveKey="1">
  5. <TabPane tab="Tab 1" key="1">
  6. Tab 1
  7. </TabPane>
  8. <TabPane tab="Tab 2" disabled key="2">
  9. Tab 2
  10. </TabPane>
  11. <TabPane tab="Tab 3" key="3">
  12. Tab 3
  13. </TabPane>
  14. </Tabs>,
  15. mountNode,
  16. );

Tabs 标签页 - 图3

图标

有图标的标签。

  1. import { Tabs, Icon } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. ReactDOM.render(
  4. <Tabs defaultActiveKey="2">
  5. <TabPane
  6. tab={
  7. <span>
  8. <Icon type="apple" />
  9. Tab 1
  10. </span>
  11. }
  12. key="1"
  13. >
  14. Tab 1
  15. </TabPane>
  16. <TabPane
  17. tab={
  18. <span>
  19. <Icon type="android" />
  20. Tab 2
  21. </span>
  22. }
  23. key="2"
  24. >
  25. Tab 2
  26. </TabPane>
  27. </Tabs>,
  28. mountNode,
  29. );

Tabs 标签页 - 图4

滑动

可以左右、上下滑动,容纳更多标签。

  1. import { Tabs, Radio } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. class SlidingTabsDemo extends React.Component {
  4. constructor(props) {
  5. super(props);
  6. this.state = {
  7. mode: 'top',
  8. };
  9. }
  10. handleModeChange = e => {
  11. const mode = e.target.value;
  12. this.setState({ mode });
  13. };
  14. render() {
  15. const { mode } = this.state;
  16. return (
  17. <div>
  18. <Radio.Group onChange={this.handleModeChange} value={mode} style={{ marginBottom: 8 }}>
  19. <Radio.Button value="top">Horizontal</Radio.Button>
  20. <Radio.Button value="left">Vertical</Radio.Button>
  21. </Radio.Group>
  22. <Tabs defaultActiveKey="1" tabPosition={mode} style={{ height: 220 }}>
  23. <TabPane tab="Tab 1" key="1">
  24. Content of tab 1
  25. </TabPane>
  26. <TabPane tab="Tab 2" key="2">
  27. Content of tab 2
  28. </TabPane>
  29. <TabPane tab="Tab 3" key="3">
  30. Content of tab 3
  31. </TabPane>
  32. <TabPane tab="Tab 4" key="4">
  33. Content of tab 4
  34. </TabPane>
  35. <TabPane tab="Tab 5" key="5">
  36. Content of tab 5
  37. </TabPane>
  38. <TabPane tab="Tab 6" key="6">
  39. Content of tab 6
  40. </TabPane>
  41. <TabPane tab="Tab 7" key="7">
  42. Content of tab 7
  43. </TabPane>
  44. <TabPane tab="Tab 8" key="8">
  45. Content of tab 8
  46. </TabPane>
  47. <TabPane tab="Tab 9" key="9">
  48. Content of tab 9
  49. </TabPane>
  50. <TabPane tab="Tab 10" key="10">
  51. Content of tab 10
  52. </TabPane>
  53. <TabPane tab="Tab 11" key="11">
  54. Content of tab 11
  55. </TabPane>
  56. </Tabs>
  57. </div>
  58. );
  59. }
  60. }
  61. ReactDOM.render(<SlidingTabsDemo />, mountNode);

Tabs 标签页 - 图5

附加内容

可以在页签右边添加附加操作。

  1. import { Tabs, Button } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. const operations = <Button>Extra Action</Button>;
  4. ReactDOM.render(
  5. <Tabs tabBarExtraContent={operations}>
  6. <TabPane tab="Tab 1" key="1">
  7. Content of tab 1
  8. </TabPane>
  9. <TabPane tab="Tab 2" key="2">
  10. Content of tab 2
  11. </TabPane>
  12. <TabPane tab="Tab 3" key="3">
  13. Content of tab 3
  14. </TabPane>
  15. </Tabs>,
  16. mountNode,
  17. );

Tabs 标签页 - 图6

大小

大号页签用在页头区域,小号用在弹出框等较狭窄的容器内。

  1. import { Tabs, Radio } from 'choerodon-ui';
  2. const { TabPane } = Tabs;
  3. class Demo extends React.Component {
  4. state = { size: 'small' };
  5. onChange = e => {
  6. this.setState({ size: e.target.value });
  7. };
  8. render() {
  9. const { size } = this.state;
  10. return (
  11. <div>
  12. <Radio.Group value={size} onChange={this.onChange} style={{ marginBottom: 16 }}>
  13. <Radio.Button value="small">Small</Radio.Button>
  14. <Radio.Button value="default">Default</Radio.Button>
  15. <Radio.Button value="large">Large</Radio.Button>
  16. </Radio.Group>
  17. <Tabs defaultActiveKey="1" size={size}>
  18. <TabPane tab="Tab 1" key="1">
  19. Content of tab 1
  20. </TabPane>
  21. <TabPane tab="Tab 2" key="2">
  22. Content of tab 2
  23. </TabPane>
  24. <TabPane tab="Tab 3" key="3">
  25. Content of tab 3
  26. </TabPane>
  27. </Tabs>
  28. </div>
  29. );
  30. }
  31. }
  32. ReactDOM.render(<Demo />, mountNode);

Tabs 标签页 - 图7

位置

有四个位置,tabPosition="left|right|top|bottom"

  1. import { Tabs, Select } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. const Option = Select.Option;
  4. class Demo extends React.Component {
  5. state = {
  6. tabPosition: 'top',
  7. };
  8. changeTabPosition = tabPosition => {
  9. this.setState({ tabPosition });
  10. };
  11. render() {
  12. return (
  13. <div>
  14. <div style={{ marginBottom: 16 }}>
  15. Tab position
  16. <Select
  17. value={this.state.tabPosition}
  18. onChange={this.changeTabPosition}
  19. dropdownMatchSelectWidth={false}
  20. >
  21. <Option value="top">top</Option>
  22. <Option value="bottom">bottom</Option>
  23. <Option value="left">left</Option>
  24. <Option value="right">right</Option>
  25. </Select>
  26. </div>
  27. <Tabs tabPosition={this.state.tabPosition}>
  28. <TabPane tab="Tab 1" key="1">
  29. Content of Tab 1
  30. </TabPane>
  31. <TabPane tab="Tab 2" key="2">
  32. Content of Tab 2
  33. </TabPane>
  34. <TabPane tab="Tab 3" key="3">
  35. Content of Tab 3
  36. </TabPane>
  37. </Tabs>
  38. </div>
  39. );
  40. }
  41. }
  42. ReactDOM.render(<Demo />, mountNode);

Tabs 标签页 - 图8

卡片式页签

另一种样式的页签,不提供对应的垂直样式。

  1. import { Tabs } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. function callback(key) {
  4. console.log(key);
  5. }
  6. ReactDOM.render(
  7. <Tabs onChange={callback} type="card">
  8. <TabPane tab="Tab 1" key="1">
  9. Content of Tab Pane 1
  10. </TabPane>
  11. <TabPane tab="Tab 2" key="2">
  12. Content of Tab Pane 2
  13. </TabPane>
  14. <TabPane tab="Tab 3" key="3">
  15. Content of Tab Pane 3
  16. </TabPane>
  17. </Tabs>,
  18. mountNode,
  19. );

Tabs 标签页 - 图9

新增和关闭页签

只有卡片样式的页签支持新增和关闭选项。使用 closable={false} 禁止关闭。

  1. import { Tabs } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. class Demo extends React.Component {
  4. constructor(props) {
  5. super(props);
  6. this.newTabIndex = 0;
  7. const panes = [
  8. { title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
  9. { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
  10. { title: 'Tab 3', content: 'Content of Tab 3', key: '3', closable: false },
  11. ];
  12. this.state = {
  13. activeKey: panes[0].key,
  14. panes,
  15. };
  16. }
  17. onChange = activeKey => {
  18. this.setState({ activeKey });
  19. };
  20. onEdit = (targetKey, action) => {
  21. this[action](targetKey);
  22. };
  23. add = () => {
  24. const panes = this.state.panes;
  25. const activeKey = `newTab${this.newTabIndex++}`;
  26. panes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
  27. this.setState({ panes, activeKey });
  28. };
  29. remove = targetKey => {
  30. let activeKey = this.state.activeKey;
  31. let lastIndex;
  32. this.state.panes.forEach((pane, i) => {
  33. if (pane.key === targetKey) {
  34. lastIndex = i - 1;
  35. }
  36. });
  37. const panes = this.state.panes.filter(pane => pane.key !== targetKey);
  38. if (lastIndex >= 0 && activeKey === targetKey) {
  39. activeKey = panes[lastIndex].key;
  40. }
  41. this.setState({ panes, activeKey });
  42. };
  43. render() {
  44. return (
  45. <Tabs
  46. onChange={this.onChange}
  47. activeKey={this.state.activeKey}
  48. type="editable-card"
  49. onEdit={this.onEdit}
  50. >
  51. {this.state.panes.map(pane => (
  52. <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
  53. {pane.content}
  54. </TabPane>
  55. ))}
  56. </Tabs>
  57. );
  58. }
  59. }
  60. ReactDOM.render(<Demo />, mountNode);

Tabs 标签页 - 图10

卡片式页签容器

用于容器顶部,需要一点额外的样式覆盖。

  1. import { Tabs } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. ReactDOM.render(
  4. <div className="card-container">
  5. <Tabs type="card">
  6. <TabPane tab="Tab Title 1" key="1">
  7. <p>Content of Tab Pane 1</p>
  8. <p>Content of Tab Pane 1</p>
  9. <p>Content of Tab Pane 1</p>
  10. </TabPane>
  11. <TabPane tab="Tab Title 2" key="2">
  12. <p>Content of Tab Pane 2</p>
  13. <p>Content of Tab Pane 2</p>
  14. <p>Content of Tab Pane 2</p>
  15. </TabPane>
  16. <TabPane tab="Tab Title 3" key="3">
  17. <p>Content of Tab Pane 3</p>
  18. <p>Content of Tab Pane 3</p>
  19. <p>Content of Tab Pane 3</p>
  20. </TabPane>
  21. </Tabs>
  22. </div>,
  23. mountNode,
  24. );
  1. .card-container > .c7n-tabs-card > .c7n-tabs-content {
  2. height: 120px;
  3. margin-top: -16px;
  4. }
  5. .card-container > .c7n-tabs-card > .c7n-tabs-content > .c7n-tabs-tabpane {
  6. background: #fff;
  7. padding: 16px;
  8. }
  9. .card-container > .c7n-tabs-card > .c7n-tabs-bar {
  10. border-color: #fff;
  11. }
  12. .card-container > .c7n-tabs-card > .c7n-tabs-bar .c7n-tabs-tab {
  13. border-color: transparent;
  14. background: transparent;
  15. }
  16. .card-container > .c7n-tabs-card > .c7n-tabs-bar .c7n-tabs-tab-active {
  17. border-color: #fff;
  18. background: #fff;
  19. }

Tabs 标签页 - 图11

自定义新增页签触发器

隐藏默认的页签增加图标,给自定义触发器绑定事件。

  1. import { Tabs, Button } from 'choerodon-ui';
  2. const TabPane = Tabs.TabPane;
  3. class Demo extends React.Component {
  4. constructor(props) {
  5. super(props);
  6. this.newTabIndex = 0;
  7. const panes = [
  8. { title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
  9. { title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
  10. ];
  11. this.state = {
  12. activeKey: panes[0].key,
  13. panes,
  14. };
  15. }
  16. onChange = activeKey => {
  17. this.setState({ activeKey });
  18. };
  19. onEdit = (targetKey, action) => {
  20. this[action](targetKey);
  21. };
  22. add = () => {
  23. const panes = this.state.panes;
  24. const activeKey = `newTab${this.newTabIndex++}`;
  25. panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
  26. this.setState({ panes, activeKey });
  27. };
  28. remove = targetKey => {
  29. let activeKey = this.state.activeKey;
  30. let lastIndex;
  31. this.state.panes.forEach((pane, i) => {
  32. if (pane.key === targetKey) {
  33. lastIndex = i - 1;
  34. }
  35. });
  36. const panes = this.state.panes.filter(pane => pane.key !== targetKey);
  37. if (lastIndex >= 0 && activeKey === targetKey) {
  38. activeKey = panes[lastIndex].key;
  39. }
  40. this.setState({ panes, activeKey });
  41. };
  42. render() {
  43. return (
  44. <div>
  45. <div style={{ marginBottom: 16 }}>
  46. <Button onClick={this.add}>ADD</Button>
  47. </div>
  48. <Tabs
  49. hideAdd
  50. onChange={this.onChange}
  51. activeKey={this.state.activeKey}
  52. type="editable-card"
  53. onEdit={this.onEdit}
  54. >
  55. {this.state.panes.map(pane => (
  56. <TabPane tab={pane.title} key={pane.key}>
  57. {pane.content}
  58. </TabPane>
  59. ))}
  60. </Tabs>
  61. </div>
  62. );
  63. }
  64. }
  65. ReactDOM.render(<Demo />, mountNode);

API

Tabs

参数说明类型默认值
activeKey当前激活 tab 面板的 keystring
animated是否使用动画切换 Tabs,在 tabPosition=top|bottom 时有效boolean | {inkBar:boolean, tabPane:boolean}true, 当 type="card" 时为 false
defaultActiveKey初始化选中面板的 key,如果没有设置 activeKeystring第一个面板
hideAdd是否隐藏加号图标,在 type="editable-card" 时有效booleanfalse
size大小,提供 large defaultsmall 三种大小string'default'
tabBarExtraContenttab bar 上额外的元素React.ReactNode
tabBarStyletab bar 的样式对象object-
tabPosition页签位置,可选值有 top right bottom leftstring'top'
type页签的基本样式,可选 linecard editable-card 类型string'line'
onChange切换面板的回调(newActiveKey, oldActiveKey) => void
onEdit新增和删除页签的回调,在 type="editable-card" 时有效(targetKey, action): void
onNextClicknext 按钮被点击的回调(e) => void
onPrevClickprev 按钮被点击的回调(e) => void
onTabClicktab 被点击的回调(tabKey) => void
tabBarGuttertabs 之间的间隙number

Tabs.TabPane

参数说明类型默认值
forceRender被隐藏时是否渲染 DOM 结构booleanfalse
key对应 activeKeystring
tab选项卡头显示文字string|ReactNode